Python 3'te göreli ithalat
Aynı dizinde başka bir dosyadan bir işlevi almak istiyorum.
Bazen from .mymodule import myfunction
ile benim için çalışıyor ama ben bazen
SystemError: Parent module '' not loaded, cannot perform relative import
Bazen from mymodule import myfunction
, ama bazen ben de almak ile çalışır
SystemError: Parent module '' not loaded, cannot perform relative import
Ben gerçekten, gerçekten burada mantık anlamıyorum, ve herhangi bir açıklama bulamadım. Bu tamamen rastgele görünüyor.
Birisi bütün bunların arkasındaki mantık nedir bana açıklayabilir mi?
CEVAP
ne yazık ki, Bu modül paketi, ve bunun içinde de olması gerekir bir komut olarak çalıştırılabilir olması gerekir, bazen. Ben nasıl herhangi bir fikir bunu başarmak?
Oldukça yaygın olan bu gibi bir düzen var
main.py
mypackage/
__init__.py
mymodule.py
myothermodule.py
...bu gibi... mymodule.py
ile
#!/usr/bin/env python3
# Exported function
def as_int(a):
return int(a)
# Test function for module
def _test():
assert as_int('1') == 1
if __name__ == '__main__':
_test()
...myothermodule.py
gibi
#!/usr/bin/env python3
from .mymodule import as_int
# Exported function
def add(a, b):
return as_int(a) as_int(b)
# Test function for module
def _test():
assert add('1', '1') == 2
if __name__ == '__main__':
_test()
...ve 20 ** bu gibi
#!/usr/bin/env python3
from mypackage.myothermodule import add
def main():
print(add('1', '1'))
if __name__ == '__main__':
main()
main.py
mypackage/mymodule.py
Çalıştır ama mypackage/myothermodule.py
, göreli ithalat nedeniyle başarısız olduğunda gayet iyi çalışıyor. ..
from .mymodule import as_int
Çalıştırmak gerekiyordu.
python3 -m mypackage.myothermodule
...ama biraz daha ayrıntılı ve iyi #!/usr/bin/env python3
gibi kayda değer bir çizgi ile karışmaz.
Bu durum için en basit düzeltme, mymodule
genel benzersiz adı varsayarsak, göreli ithalat kullanarak önlemek için ve sadece kullanın
from mymodule import as_int
...eğer özel değilse, ya da paket yapısının daha karmaşık olmasına rağmen, dizin PYTHONPATH
paket içeren dizini dahil etmek gerekir ve böyle yap
from mypackage.mymodule import as_int
eğer "kod PYTHONPATH
ilk bu... ... frob" kutunun dışında çalışmak istiyorsanız ...ya da
import sys
import os
PACKAGE_PARENT = '..'
SCRIPT_DIR = os.path.dirname(os.path.realpath(os.path.join(os.getcwd(), os.path.expanduser(__file__))))
sys.path.append(os.path.normpath(os.path.join(SCRIPT_DIR, PACKAGE_PARENT)))
from mypackage.mymodule import as_int
Biraz acı, ama an email belirli bir Guido tarafından yazılmış van Rossum neden olduğu konusunda hiçbir fikri yok...
-1 ben
__main__
herhangi bir diğer önerilen twiddlings bu ve makine. Sadece kullanmak durumunda buna komut çalışıyor gibi görünüyor bir her zaman olduğu gibi gördüğüm bir modül dizin, içinde yaşadığı antipattern. Beni ikna etmen gerekir benim nasıl yandığımı o değil.
İster çalışan komut dosyaları bir paketin içindeki bir antipattern veya öznel, ama şahsen ben bulmak gerçekten yararlı bir paket içeren bazı özel wxPython Aletler, yani çalıştırmak komut dosyası için herhangi bir kaynak dosyaları için görüntüleme wx.Frame
içeren sadece bu widget için test amaçlı.