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?

Joan Venge
źródło

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 :)

Paolo Bergantino
źródło
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.

Rick Copeland
źródło
@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

ndemou
źródło
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.

SingleNegationElimination
źródło
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).

John Millikin
źródło
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')
e18r
źródło
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.

Ale
źródło