İçe aktarmaya çalışırken Python dosyalarında tire kullanmak uygun mudur?


149

Temelde gibi bir python dosyası olduğunda:

python-code.py

ve kullan:

import (python-code)

yorumlayıcı bana sözdizimi hatası veriyor.

Nasıl düzelteceğimize dair bir fikri olan? Python dosya adlarında tire işaretleri yasadışı mı?

Yanıtlar:


167

Python Kodu için Stil Kılavuzu PEP 8'e göz atmalısınız :

Paket ve Modül Adları Modüllerin kısa, tamamen küçük harfli adları olmalıdır. Okunabilirliği geliştirirse, modül adında alt çizgiler kullanılabilir. Alt çizgi kullanımı önerilmez, ancak Python paketlerinin de kısa, tümü küçük harfli adları olmalıdır.

Modül adları dosya adlarına eşlendiğinden ve bazı dosya sistemleri büyük / küçük harf duyarsız ve kısaltılmış uzun adlar olduğundan, modül adlarının oldukça kısa olarak seçilmesi önemlidir - bu Unix'te sorun olmayacaktır, ancak eski Mac veya Windows sürümlerine veya DOS'a aktarıldığında sorun.

Başka bir deyişle: dosyanızı yeniden adlandırın :)


75
sorunun stil ile ilgisi yoktur, sözdizimi hatasıdır

4
Aşağıda gösterildiği gibi, yine de bu ada sahip bir dosyaya sahip olmak mümkündür, bu nedenle stil kılavuzu çok önemlidir.
Paolo Bergantino

5
İçe aktarmayı açıkça önlemek istediğinizde Python dizininde ve dosya adlarında tire kullanmak çok yararlı olabilir. Örneğin, bir Django projesinde (Python'da yazılmış), uygulama olarak adreslenmemesi gereken komut dosyalarınız olabilir. Bunları benzer bir klasöre koyabilir ops-scriptsve normal bir paket ad alanı yaklaşımı kullanılarak içe aktarılamayacağını bilirsiniz. Veya stop-website.pybenzer bir efekt için tek bir komut dosyası adlandırılabilir . Bunlardan herhangi biri hala runpyve diğer bazı yöntemlerle içe aktarılabilir , ancak bu bazı yaygın hataların önlenmesine yardımcı olur.
Chris Johnson

Bir modülü yeniden adlandırmak, özellikle başka bir standarda güveniyorsanız sorunlu olabilir. Benim durumumda, cgi-binoldukça standart afaik olan klasörde (onlara unitttests yapıyor) python cgi dosyaları kullanıyorum . Böyle nadir bir durum yoksa, üzerinde kontrolünüz varsa modülünüzü kesinlikle yeniden adlandırın.
NuclearPeon

1
Ben sadece PyDev tire ile dizin adlarına izin vereceğini keşfetti, ancak sınıfları ve / veya iç değişkenleri o dizinde bulunan .py dosyalarında göstermez.
user5920660

123

Kodunuzda dikkat etmeniz gereken bir diğer şey de içe aktarmanın bir işlev olmamasıdır. Yani import(python-code)olmalıdır import python-codebazıları zaten söylediğim gibi "ithal piton eksi kod" olarak yorumlanır hangi, amaçladığınız gibi değil. Gerçekten adında tire bulunan bir dosyayı içe aktarmanız gerekiyorsa aşağıdakileri yapabilirsiniz ::

python_code = __import__('python-code')

Ancak, yukarıda da belirtildiği gibi, bu gerçekten tavsiye edilmez. Kontrol ettiğiniz bir şeyse dosya adını değiştirmeniz gerekir.


@KevinAudleman, hecelenmiş bir dosyayla içe aktarma lib'i kullanmaya çalışan bir örneğiniz var mı? Denedim ve başarısız oldum.
Tom Hale

@TomHale importlib.import_module ('abmodule-1') çalışmalıdır. İmport_module'ünüz çalışmıyorsa, normal bir içe aktarmanın da çalışmadığını düşünüyorum.
Ian Lin

64

TLDR

Kısa çizgiler yasadışı değildir, ancak bunları 3 nedenden dolayı kullanmamalısınız:

  1. Çizgili dosyaları içe aktarmak için özel sözdizimine ihtiyacınız var
  2. Kimse kısa çizgi ile bir modül adı beklemiyor
  3. Python Stil Rehberinin önerilerine aykırı

Kesinlikle tire ile bir dosya adı almanız gerekiyorsa, özel sözdizimi şudur:

module_name = __import__('module-name')

Neden özel sözdizimine ihtiyacımız olduğunu merak ediyor musunuz?

Özel sözdiziminin nedeni, yazarken import somenametanımlayıcıya sahip bir modül nesnesi oluşturmanızdır somename(böylece daha sonra örneğin ile kullanabilirsiniz somename.funcname). Tabii ki module-namegeçerli bir tanımlayıcı değildir ve dolayısıyla geçerli bir tanımlayıcı veren özel sözdizimi değildir.

Modül adının neden geçerli tanımlayıcı olmadığını anlamıyorsunuz?

Endişelenme - Ben de yapmadım. İşte size yardımcı olacak bir ipucu: Bu piton hattında Görünüş: x=var1-var2. Ödevin sağ tarafında bir çıkarma veya kısa çizgi içeren bir değişken adı görüyor musunuz?

PS

Tek bir yerde diğer tüm cevaplardan en alakalı bilgi parçaları olarak kabul ettiğim şey hariç, cevabımda hiçbir şey orijinal değil


Bu içe aktarma bir pip paketi içinde bir tire ile kullanmaya çalışıyorum. psycopg2_binary = import_module('psycopg2-binary'). Hata => ModuleNotFoundError: No module named 'psycopg2-binary'. Ama psycopg2-binaryyüklü. Nasıl ekleyeceğimi bilmiyorum.
Mote Zart

Belki de bu bir yol sorunudur. Chrisyeh96.github.io/2017/08/08/…
ndemou

32

Sorun şu ki python-codebir tanımlayıcı değil. Ayrıştırıcı bunu pythoneksi olarak görür code. Tabii ki bu istediğini yapmaz. Aynı zamanda geçerli bir python tanımlayıcısı olan bir dosya adı kullanmanız gerekecektir. -Simgesini alt çizgi ile değiştirmeyi deneyin .


4
+1. Python kaynak kodunun dosya adının geçerli bir tanımlayıcı olması gerektiğini asla düşünmeyin, çünkü dosya adının modül nesnesine başvurmak için kullanılacağını unutmayın.
andy

5

Muhtemelen bunu bir __import__hack yoluyla içe aktarabilirsiniz , ancak nasıl olduğunu bilmiyorsanız yapmamalısınız. Python modül adları geçerli değişken adları ("tanımlayıcılar") olmalıdır - yani bir modülünüz foo_barvarsa, bunu Python ( print foo_bar) içinden kullanabilirsiniz . Tuhaf bir adla ( print foo-bar-> sözdizimi hatası) bunu yapamazsınız .


5

Python 3'te import_module kullanın :

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

Daha genel olarak,

import_module('package.subpackage.module')

1

Doğru dosya adlandırma en iyi yol olmasına rağmen, python-codekontrolümüz altında değilse, bir kesmek kesmek __import__, kopyalamak, yeniden adlandırmak veya diğer yazarların kodlarıyla uğraşmaktan daha iyidir. Ancak, denedim ve .pyuzantı ekleyerek dosyayı yeniden adlandırmadıkça işe yaramadı . Nasıl bir açıklama almak için doktora baktıktan sonra .py, ben bununla sona erdi:

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

python-codecİlk çalıştırmada yeni bir dosya oluşturdu .

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.