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.