python NameError: genel adı '__file__' tanımlı değil


112

Bu kodu python 2.7'de çalıştırdığımda şu hatayı alıyorum:

Traceback (most recent call last):
File "C:\Python26\Lib\site-packages\pyutilib.subprocess-3.5.4\setup.py", line 30, in <module>
    long_description = read('README.txt'),
  File "C:\Python26\Lib\site-packages\pyutilib.subprocess-3.5.4\setup.py", line 19, in read
    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()
NameError: global name '__file__' is not defined

kod:

import os
from setuptools import setup


def read(*rnames):
    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()


setup(name="pyutilib.subprocess",
    version='3.5.4',
    maintainer='William E. Hart',
    maintainer_email='wehart@sandia.gov',
    url = 'https://software.sandia.gov/svn/public/pyutilib/pyutilib.subprocess',
    license = 'BSD',
    platforms = ["any"],
    description = 'PyUtilib utilites for managing subprocesses.',
    long_description = read('README.txt'),
    classifiers = [
        'Development Status :: 4 - Beta',
        'Intended Audience :: End Users/Desktop',
        'License :: OSI Approved :: BSD License',
        'Natural Language :: English',
        'Operating System :: Microsoft :: Windows',
        'Operating System :: Unix',
        'Programming Language :: Python',
        'Programming Language :: Unix Shell',
        'Topic :: Scientific/Engineering :: Mathematics',
        'Topic :: Software Development :: Libraries :: Python Modules'],
      packages=['pyutilib', 'pyutilib.subprocess', 'pyutilib.subprocess.tests'],
      keywords=['utility'],
      namespace_packages=['pyutilib'],
      install_requires=['pyutilib.common', 'pyutilib.services']
      )

Yanıtlar:


134

Bu hata, bu satırı os.path.join(os.path.dirname(__file__))python etkileşimli kabuğuna eklediğinizde ortaya çıkar .

Python Shelliçindeki mevcut dosya yolunu algılamıyor __file__ve filepathbu satırı eklediğiniz ile ilgili

Yani bu çizgiyi yazmalı os.path.join(os.path.dirname(__file__))içinde file.py. ve sonra çalıştırın python file.py, çalışır çünkü dosya yolunuzu alır.


8
tam olarak benim deneyimim. ama bir kabuk içinde nasıl çalıştırılır?
s2t2

1
Ancak file.pybir komut dosyasından çalıştırmak için, örneğin komut dosyanızla aynı dizine koyarsınız. Yani koşmadan önce bu dizine gitmeniz gerekiyor file.py... Yani hala daha iyi bir şey aranıyor.
ztyh

Yani Emacs, Cc Cp'yi kullandığınızda etkileşimli bir kabuk kullanıyor? piton kabuğu. Bu kabuğu, dosyayı çalıştıran bir terminalmiş gibi kullanmanın bir yolu var mı? Kabuğu çalıştırmak için 3 seçenek vardır: CMD DEDICATED SHOW Bunlardan biri bunu yapar mı?
sinekonata

18

PyInstaller ve Py2exe ile aynı sorunu yaşadım, bu yüzden cx-freeze'deki SSS'deki çözüme rastladım.

Komut dosyanızı konsoldan veya bir uygulama olarak kullanırken, buradaki işlevler size "gerçek dosya yolunu" değil "yürütme yolunu" sunacaktır:

print(os.getcwd())
print(sys.argv[0])
print(os.path.dirname(os.path.realpath('__file__')))

Kaynak:
http://cx-freeze.readthedocs.org/en/latest/faq.html

Eski satırınız (ilk soru):

def read(*rnames):
return open(os.path.join(os.path.dirname(__file__), *rnames)).read()

Kod satırınızı aşağıdaki kod parçacığı ile değiştirin.

def find_data_file(filename):
    if getattr(sys, 'frozen', False):
        # The application is frozen
        datadir = os.path.dirname(sys.executable)
    else:
        # The application is not frozen
        # Change this bit to match where you store your data files:
        datadir = os.path.dirname(__file__)

    return os.path.join(datadir, filename)

Yukarıdaki kodla, uygulamanızı işletim sisteminizin yoluna ekleyebilir, uygulamanızın veri / yapılandırma dosyalarını bulamaması sorunu olmadan herhangi bir yerde çalıştırabilirsiniz.

Python ile test edildi:

  • 3.3.4
  • 2.7.13

12

kodlarınızı aşağıdaki gibi değiştirin! benim için çalışıyor. '

os.path.dirname(os.path.abspath("__file__"))

7
Doc'aos.getcwd() göre gerçekten kullandığınızı düşünüyorum ve bu anlamsız. "__file__"
davidlatwe

5
Bunun neden olumlu oyları var? Pek çok insan bunu aldı ve işlenmemiş bir istisnadan kurtulduğu için doğru olduğunu mu varsaydılar ?? Bu doğru bir çözüm değil insanlar . __file__Yaptığı şey , kelimenin tam anlamıyla " " adlı bir dosyaya sahip olduğunuzu ve eğer varsa, hangi klasörde olabileceğini söylemek !
Todd

11

__file__Beklendiği gibi çalışmayan vakalarla karşılaştım . Ama şu ana kadar beni hayal kırıklığına uğratmadı:

import inspect
src_file_path = inspect.getfile(lambda: None)

Bu, C'lerin Python analoğuna en yakın şeydir __FILE__.

Python'un davranışı C'lerden __file__çok farklıdır __FILE__. C sürümü size kaynak dosyanın orijinal yolunu verecektir. Bu, hataları günlüğe kaydetmede ve hangi kaynak dosyada hatanın bulunduğunu bilmede yararlıdır.

Python size __file__yalnızca şu anda çalışmakta olan dosyanın adını verir, bu da günlük çıktısında pek kullanışlı olmayabilir.


2
Bu, python başka bir uygulamaya gömülü olduğunda da çalışır
sdaau

os.path.dirname(os.path.realpath(...))Yöntemden çok bunda şansım oldu .
Bay S

1
Bu en iyi cevap olmalı.
183.amir


9

Dosyayı bir dizge olarak ele alarak çözdüm, yani yerine koyun "__file__"(tırnak işaretleriyle birlikte!)__file__

Bu benim için iyi çalışıyor:

wk_dir = os.path.dirname(os.path.realpath('__file__'))

8
Bu gerçekten işe yarıyor, ama nedenini anlayamıyorum. Neden "__file__"tırnak işaretleri arasında tırnak işaretleri __file__olmadan farklı işlem yapılır ?
Gio

5
Çünkü eksik global değişkeni referans almıyor. Bunun yerine, ' dosya ' dizesini yolun bir parçası olarak ele alır.
JoshVarty

42
Bu, dosyanın bulunduğu dizini döndürmez, sadece geçerli çalışma dizinini (python çağrıldığı yerde) döndürür. -1
Xiangyu

8
Yerine herhangi bir dosya adı yapılacaktır "__file__". Örn realpath('nonexistentfile.whatever').
Ocak

35
Bu cevap, yanlış ve yanıltıcı olduğu için gerçekten kaldırılmalıdır. Bu kadar yüksek oy alması oldukça endişe verici ...
Cas

6

Eğer aradığınız tek os.getcwd()şey os.path.dirname(__file__)mevcut çalışma dizininizi almaksa, kodunuzun başka bir yerinde çalışma dizinini değiştirmediğiniz sürece size aynı şeyi verecektir . os.getcwd()ayrıca etkileşimli modda çalışır.

Yani os.path.join(os.path.dirname(__file__)) olur os.path.join(os.getcwd())


Bu bir kazanan
Shawn

1
Bu cevap doğru değil . os.path.dirname(__file__)ile aynı şeyi rapor etmiyor os.getcwd(). Size verdiği şey dosyanın dir adıdır. os.getcwd()Bunun eşleştiği ortaya çıkarsa, bu sadece bir tesadüftür.
Todd

4

Python kabuğundan komutları çalıştırıyorsanız bunu alacaksınız:

>>> __file__
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name '__file__' is not defined

Dosyayı doğrudan pythonkomuta argüman olarak ileterek çalıştırmanız gerekir :

$ python somefile.py

Senin durumunda, gerçekten olmalı python setup.py install


2

Yapabilecekleriniz aşağıdakileri kullanmaktır

import os
if '__file__' in vars():
    wk_dir = os.path.dirname(os.path.realpath('__file__'))
else:
    print('We are running the script interactively')

Burada dizeyi kullanmanın '__file__'gerçekten gerçek değişkene atıfta bulunduğuna dikkat edin __file__. Elbette bunu kendiniz de deneyebilirsiniz ..

Bu çözümün ek avantajı, bir komut dosyasını kısmen etkileşimli olarak çalıştırdığınızda (örneğin, onu test etmek / geliştirmek için) esnekliktir ve komut satırı aracılığıyla çalıştırabilirsiniz.


Notunuzla ilgili olarak, '__file__'geçerli bir değişken adı iken ve ifkoşulunuz doğru os.path.realpath('__file__')olacak '__file__', dosyanın adı gibi davranan sahte bir yol döndürür . İhtiyacınız olan tek şey, üzerinden üst dizini ise, os.path.dirname()sorun değil - ama bu bir "hack". @zwep
Todd

Ayrıca __file__bir kaynak dosyadan referans vermek , içinde kullanıldığı dosyanın yolunu alacaktır - ile aynı şey değildir os.getcwd(). Her zaman sizin wk_dir- veya iş dizininiz olmayacaktır .
Todd

2

Bir dosyayı komut satırı üzerinden yürütüyorsanız, bu hack'i kullanabilirsiniz.

import traceback

def get_this_filename():
    try:
        raise NotImplementedError("No error")
    except Exception as e:
        exc_type, exc_value, exc_traceback = sys.exc_info()
        filename = traceback.extract_tb(exc_traceback)[-1].filename
    return filename

Bu benim için UnrealEnginePython konsolunda çalıştı, py.exec myfile.py


1

Jupyter defterinde de aynı sorunu yaşadım. 'Os.path.split (os.path.realpath ( dosya ))' kullanırken, dizüstü bilgisayar bir hata veriyordu.

Bu yüzden ' dosya ' kullandım. Mükemmel çalıştı.


0

Aynı sorunu yaşıyorum ve muhtemelen aynı öğreticiyi kullanıyorum . İşlev tanımı:

def read(*rnames):
    return open(os.path.join(os.path.dirname(__file__), *rnames)).read()

Buggy, çünkü os.path.dirname(__file__)ihtiyacınız olanı iade etmeyecek. Değiştirmeyi deneyin os.path.dirname(__file__)ile os.path.dirname(os.path.abspath(__file__)):

def read(*rnames):
    return open(os.path.join(os.path.dirname(os.path.abspath(__file__)), *rnames)).read()

Az önce Andrew'a, mevcut belgelerdeki kod parçacığının çalışmadığını bildirdim, umarım düzeltilecektir.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.