Czy można używać myślników w plikach Pythona podczas próby ich zaimportowania?


149

Zasadniczo, gdy mam plik Pythona, taki jak:

python-code.py

I użyć:

import (python-code)

interpreter podaje mi błąd składniowy.

Jakieś pomysły, jak to naprawić? Czy myślniki są niedozwolone w nazwach plików Pythona?

Odpowiedzi:


167

Powinieneś sprawdzić PEP 8 , przewodnik po stylu dla kodu w języku Python:

Nazwy pakietów i modułów Moduły powinny mieć krótkie nazwy składające się wyłącznie z małych liter. Podkreślenia mogą być używane w nazwie modułu, jeśli poprawia to czytelność. Pakiety Pythona powinny również mieć krótkie nazwy składające się wyłącznie z małych liter, chociaż odradza się stosowanie podkreślenia.

Ponieważ nazwy modułów są mapowane na nazwy plików, a niektóre systemy plików nie uwzględniają wielkości liter i obcinają długie nazwy, ważne jest, aby nazwy modułów były dość krótkie - nie będzie to problem w systemie Unix, ale może to być problem, gdy kod jest transportowany do starszych wersji Mac, Windows lub DOS.

Innymi słowy: zmień nazwę pliku :)


75
problem nie ma nic wspólnego ze stylem, jest to błąd składniowy

4
Jak pokazano poniżej, nadal można mieć plik o tej nazwie, więc przewodnik po stylach jest bardzo istotny.
— Paolo Bergantino

5
Używanie łączników w nazwach katalogów i plików w języku Python może być bardzo pomocne, gdy jawnie chcesz zapobiec importom. Na przykład w (powiedzmy) projekcie Django, możesz mieć skrypty napisane w Pythonie, które nie powinny być adresowalne jako aplikacje. Możesz umieścić je w folderze takim jak ops-scriptsi wiedzieć, że nie można ich zaimportować przy użyciu normalnego podejścia do przestrzeni nazw pakietu. Można też nazwać pojedynczy skrypt stop-website.pydla podobnego efektu. Każdy z nich można nadal importować przy użyciu runpyi innych metod, ale pomaga to uniknąć niektórych typowych błędów.
— Chris Johnson

Zmiana nazwy modułu może być problematyczna, zwłaszcza jeśli opierasz się na innym standardzie. W moim przypadku używam plików cgi Pythona w cgi-binfolderze (robię na nich unitttesty), co jest dość standardowym afaikiem. Jeśli nie masz tak rzadkiego przypadku, zdecydowanie zmień nazwę modułu, jeśli masz nad nim kontrolę.
— NuclearPeon

1
Właśnie odkryłem, że PyDev zezwoli na nazwy katalogów z myślnikami, ale nie pokaże klas i / lub zmiennych wewnętrznych w plikach .py, które są zawarte w tym katalogu.
— user5920660

123

Inną rzeczą, na którą należy zwrócić uwagę w kodzie, jest to, że import nie jest funkcją. Więc import(python-code)powinno być to, import python-codeco, jak niektórzy już wspominali, jest interpretowane jako „import pythona bez kodu”, a nie to, co zamierzałeś. Jeśli naprawdę potrzebujesz zaimportować plik z myślnikiem w nazwie, możesz wykonać następujące czynności:

python_code = __import__('python-code')

Ale, jak wspomniano powyżej, nie jest to zalecane. Powinieneś zmienić nazwę pliku, jeśli jest to coś, co kontrolujesz.


@KevinAudleman czy masz działający przykład użycia biblioteki importu z dzielonym plikiem? Próbowałem i zawiodłem.
— Tom Hale,

@TomHale importlib.import_module ('abmodule-1') powinno działać. Jeśli twój import_module nie działa, myślę, że normalny import również nie zadziała.
— Ian Lin

64

TLDR

Kreski nie są nielegalne, ale nie powinieneś ich używać z 3 powodów:

  1. Aby importować pliki z myślnikami, potrzebujesz specjalnej składni
  2. Nikt nie oczekuje nazwy modułu z myślnikiem
  3. Jest to sprzeczne z zaleceniami przewodnika po stylu Pythona

Jeśli zdecydowanie musisz zaimportować nazwę pliku z myślnikiem, specjalna składnia jest następująca:

module_name = __import__('module-name')

Ciekawi Cię, dlaczego potrzebujemy specjalnej składni?

Powodem specjalnej składni jest to, że kiedy piszesz import somename, tworzysz obiekt modułu z identyfikatorem somename(więc możesz go później użyć np somename.funcname.). Oczywiście module-namenie jest to poprawny identyfikator, stąd specjalna składnia, która daje prawidłowy identyfikator.

Nie rozumiesz, dlaczego nazwa modułu nie jest prawidłowym identyfikatorem?

Nie martw się - ja też nie. Oto wskazówka, aby pomóc: Spójrz na tej linii Pythona: x=var1-var2. Czy widzisz odejmowanie po prawej stronie przypisania lub nazwę zmiennej z myślnikiem?

PS

W mojej odpowiedzi nie ma nic oryginalnego, z wyjątkiem umieszczenia w jednym miejscu tego, co uważam za najbardziej odpowiednie fragmenty informacji ze wszystkich innych odpowiedzi


Próbuję użyć tego importu pakietu pip z łącznikiem w nim. psycopg2_binary = import_module('psycopg2-binary'). Błąd => ModuleNotFoundError: No module named 'psycopg2-binary'. Ale psycopg2-binaryjest zainstalowany. Nie mam pojęcia, jak to uwzględnić.
— Mote Zart

Może to kwestia ścieżki. Spójrz na chrisyeh96.github.io/2017/08/08/…
— ndemou

32

Problem w tym, że python-codenie jest to identyfikator. Parser widzi to jako pythonminus code. Oczywiście to nie zrobi tego, o co prosisz. Będziesz musiał użyć nazwy pliku, która jest również prawidłowym identyfikatorem Pythona. Spróbuj zastąpić -znak podkreśleniem.


4
+1. Nigdy nie sądziłem, że nazwa pliku kodu źródłowego w Pythonie powinna być poprawnym identyfikatorem, ponieważ nazwa pliku będzie używana do odwoływania się do obiektu modułu.
— andy

5

Prawdopodobnie mógł zaimportować go przez jakiś __import__hack, ale jeśli jeszcze nie wiem jak, nie należy. Nazwy modułów w Pythonie powinny być poprawnymi nazwami zmiennych („identyfikatorami”) - oznacza to, że jeśli masz moduł foo_bar, możesz go używać z poziomu Python ( print foo_bar). Nie byłbyś w stanie tego zrobić z dziwną nazwą ( print foo-bar-> błąd składni).


5

W Pythonie 3 użyj import_module :

from importlib import import_module
python_code = import_module('python-code')

Bardziej ogólnie,

import_module('package.subpackage.module')

1

Chociaż prawidłowe nazewnictwo plików jest najlepszym rozwiązaniem, jeśli python-codenie jest to pod naszą kontrolą, hackowanie __import__jest lepsze niż kopiowanie, zmiana nazwy lub inne manipulowanie kodem innych autorów. Jednak spróbowałem i nie zadziałało, chyba że zmieniłem nazwę pliku, dodając .pyrozszerzenie. Po przejrzeniu dokumentu w celu uzyskania opisu .py, skończyło się na tym:

import imp

try:
    python_code_file = open("python-code")
    python_code = imp.load_module('python_code', python_code_file, './python-code', ('.py', 'U', 1))
finally:
    python_code_file.close()

Utworzył nowy plik python-codecprzy pierwszym uruchomieniu.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.