2010-11-07 24 views
19

Sadece modül adının bir dizesiyle dinamik olarak içe aktarmak istediğim bir Python modülüne sahibim. Normalde importlib veya __import__ kullanıyorum ve bu modülde hangi nesnelerini aktarmak istediğimi bildiğimden oldukça iyi çalışıyor, ancak import * eşdeğerini dinamik olarak yapmanın bir yolu var. Ya da daha iyi bir yaklaşım var mı?Her şeyi (*) dinamik olarak bir modülden içe aktarma

Genel olarak import * kullanmak için kötü uygulama biliyorum, ancak almaya çalıştığım modüller otomatik olarak anında oluşturulur ve adresleme sınıfını içeren tam modülünü bilmenin bir yolu yoktur.

Teşekkürler.

+0

Yani, - bunu yapmak için güzel bir şey olmazdı. __import__ ile alınan modülü bir adaya atamayı ve üyelerine ulaşmak için "getattr" ve hatta nokta sözdizimini kullanmayı düşünmelisiniz. – jsbueno

cevap

5

Çirkin hacky koduyla geldim, python 2.6'da çalışıyor. Ben bu olsa yapmak akıllıca şey olup olmadığından emin değilim, belki burada diğer bazı insanlar bazı fikir var:

test = __import__('os',globals(),locals()) 
for k in dir(test): 
    globals()[k] = test.__dict__[k] 
Muhtemelen yapmak için buraya bir onay koymak istiyorum

Eğer bir şey üzerine yazma olmadığından emin genel ad alanı. Muhtemelen globals parçasından kaçabilir ve sadece ilgi alanınız için her dinamik olarak aktarılan modülü gözden geçirebilirsiniz. Bu muhtemelen, global ad alanını ithal ettiğiniz her şeyle kirletmekten çok daha iyi olacaktır. tüm isimler, çünkü

globals().update(importlib.import_module('some.package').__dict__) 

Not a_module.__dict__ kullanılarak from a_module import * olarak aynı olmadığını Örneğin:

, sınıf dicts için urllib2 gelen istek

test = __import__('urllib2',globals(),locals()) 
cls = None 
if 'Request' in dir(test): 
    cls = test.__dict__['Request'] 
    # you found the class now you can use it! 
    cls('http://test.com') 
+0

Yaptığınız şey, ilgili "sınıf" modüllerinin her birinin içeriğini ilgi alanı adı için aramaktır. En azından aradığın sınıfın adını bilmeni istiyorum. Cevabımı size örnek vermek için düzenledim. – GWW

+2

Aslında bu, yoyu düşünmekten daha az saçmadır - " import *" ifadesinden tam olarak aynı etkiye sahiptir - bu ifadenin geçerli globals sözlüğünü güncelleyeceği şekilde. Bu, globals() çağrısıyla kurtarılan aynı sözlüktür. "Çekler" gelince OP hakkında uyarırsınız: "import *" un kendisini basitçe her şeyin üzerine yazdığını unutmayın :-) – jsbueno

+0

Sanırım o kadar da kötü değil. Sanırım her zaman python'da işleri yapmak için daha şık bir yol varmış gibi hissediyorum. – GWW

0

Bunu yapmayı düşünebilmemin tek yolu, exec() kullanmak ve anında importlib komutunu dinamik olarak oluşturmaktır.

+1

Gördüğünüz gibi, daha iyi yollar var. – jsbueno

+2

Evet, şimdi görebiliyorum :) – g19fanatic

20

kullanın update adlandırıldığını söylüyor "İçe aktarılan", sadece __all__'dan değil veya _ ile başlamıyor.

+4

Bu, GWW'nin yanıtından biraz daha iyi, çünkü modül üzerinde yineleme yerine güncelleme kullanıyor. –

2

aşağıdaki son derece günahkâr olup araf mahkûm eder veya listelenen @GWW gibi bu işi yapmak için yollar varken kötü

# module A 
myvar = "hello" 

# module B 
import inspect 
def dyn_import_all(modpath): 
    """Incredibly hackish way to load into caller's global namespace""" 
    exec('from ' + modpath + ' import *', inspect.stack()[1][0].f_globals) 

# module C 
from module B import dyn_import_all 
def print_from(modpath): 
    dyn_import_all(modpath) 
    print(myvar) 
+1

os.system'i ('rm -rf .... 'unutmuştunuz .. sonunda – gauteh

İlgili konular