Adını (bir dize) kullanarak bir modülün bir işlevi çağırmak

oy
1k

Ne bir Python programında işlevin adını taşıyan bir dize verilen bir işlevi çağırarak hakkında gitmek için en iyi yoldur. Örneğin, ben bir modül olduğunu varsayalım foo, ben içerikleri olan bir dize var bar. Çağırmadan hakkında gitmek için en iyi yolu nedir foo.bar()?

Ben sadece kullanmayın yüzden fonksiyonun dönüş değerini almak gerekir eval. Ben kullanarak bunu nasıl anladım evalo işlev çağrısının sonucunu döndüren bir geçici işlevini tanımlamak için, ama bunu yapmak daha şık bir yolu olduğunu umut ediyorum.

Oluştur 06/08/2008 saat 04:36
kaynak kullanıcı
Diğer dillerde...                            


12 cevaplar

oy
1k

Modül varsayarak fooyöntemi ile bar:

import foo
method_to_call = getattr(foo, 'bar')
result = method_to_call()

Bildiğim kadarıyla o gider, hat 2 ve 3 için sıkıştırılmış olabilir:

result = getattr(foo, 'bar')()

bu senin kullanım örneği için daha mantıklı eğer. Sen kullanabilirsiniz getattrsınıf örneği bağımlı yöntemleri, modül düzeyinde yöntemden, sınıf yöntemleri bu şekilde ... liste uzayıp gidiyor.

Cevap 06/08/2008 saat 04:57
kaynak kullanıcı

oy
387
locals()["myfunction"]()

veya

globals()["myfunction"]()

Yerlilerin bir akım yerel simge tablosuna bir sözlük döndürür. globaller global simge tablosu ile bir sözlük döndürür.

Cevap 07/05/2009 saat 13:45
kaynak kullanıcı

oy
229

Patrick çözüm muhtemelen en temiz olduğunu. dinamik hem de modül almak gerekiyorsa, hoşuna alabilirsiniz:

module = __import__('foo')
func = getattr(module, 'bar')
func()
Cevap 07/08/2008 saat 12:35
kaynak kullanıcı

oy
77

Sadece basit bir katkı. Biz örneğine ihtiyaç sınıfı aynı dosyada ise, böyle bir şey kullanabilirsiniz:

# Get class from globals and create an instance
m = globals()['our_class']()

# Get the function (from the instance) that we need to call
func = getattr(m, 'function_name')

# Call it
func()

Örneğin:

class A:
    def __init__(self):
        pass

    def sampleFunc(self, arg):
        print('you called sampleFunc({})'.format(arg))

m = globals()['A']()
func = getattr(m, 'sampleFunc')
func('sample arg')

# Sample, all on one line
getattr(globals()['A'](), 'sampleFunc')('sample arg')

Ve, bir sınıf ise:

def sampleFunc(arg):
    print('you called sampleFunc({})'.format(arg))

globals()['sampleFunc']('sample arg')
Cevap 19/08/2012 saat 10:40
kaynak kullanıcı

oy
64

bir işleve tam bir piton yolu ile bir dize, göz önüne alındığında, bu dediğim fonksiyonun sonucunu alma konusunda nasıl gittiğini geçerli:

import importlib
function_string = 'mypackage.mymodule.myfunc'
mod_name, func_name = function_string.rsplit('.',1)
mod = importlib.import_module(mod_name)
func = getattr(mod, func_name)
result = func()
Cevap 16/10/2013 saat 01:24
kaynak kullanıcı

oy
30

Cevap (umarım) Tek istediğim kimse

davranış gibi Eval

getattr(locals().get("foo") or globals().get("foo"), "bar")()

Neden otomatik içe aktarma eklemeyin

getattr(
    locals().get("foo") or 
    globals().get("foo") or
    __import__("foo"), 
"bar")()

durumda biz kontrol etmek istiyorum ekstra sözlükleri var

getattr(next((x for x in (f("foo") for f in 
                          [locals().get, globals().get, 
                           self.__dict__.get, __import__]) 
              if x)),
"bar")()

Daha derine inmemiz lazım

getattr(next((x for x in (f("foo") for f in 
              ([locals().get, globals().get, self.__dict__.get] +
               [d.get for d in (list(dd.values()) for dd in 
                                [locals(),globals(),self.__dict__]
                                if isinstance(dd,dict))
                if isinstance(d,dict)] + 
               [__import__])) 
        if x)),
"bar")()
Cevap 09/04/2014 saat 11:17
kaynak kullanıcı

oy
26

Göre en iyi cevabı Python programlama SSS olacaktır:

functions = {'myfoo': foo.bar}

mystring = 'myfoo'
if mystring in functions:
    functions[mystring]()

Bu tekniğin en önemli avantajı, dizeleri fonksiyonlarının adlarla eşleşmesi gerekir kalmamasıdır. Bu aynı zamanda, bir olgu yapısını taklit etmek için kullanılan birincil bir tekniktir

Cevap 24/10/2016 saat 13:20
kaynak kullanıcı

oy
18

Eğer bir dize olarak işlev (veya sınıf) adını ve uygulama adı geçmesine gerekirse bu değer ne için, o zaman yapabilirsiniz:

myFnName  = "MyFn"
myAppName = "MyApp"
app = sys.modules[myAppName]
fn  = getattr(app,myFnName)
Cevap 14/02/2012 saat 06:55
kaynak kullanıcı

oy
15

Bunu dene. Bu hala eval kullanırken, sadece için kullanır geçerli bağlamdan işlevini çağırmak . Ardından, istediğiniz gibi kullanmak gerçek fonksiyonu var.

Bu benim için ana yararı işlevini çağırma noktasında herhangi eval ile ilgili hataları alacak olmasıdır. O zaman alacak sadece Aradığınızda fonksiyon ilgili hatalar.

def say_hello(name):
    print 'Hello {}!'.format(name)

# get the function by name
method_name = 'say_hello'
method = eval(method_name)

# call it like a regular function later
args = ['friend']
kwargs = {}
method(*args, **kwargs)
Cevap 07/12/2016 saat 18:29
kaynak kullanıcı

oy
13

önerilerin bir hiçbiri bana yardımcı oldu. Ben bu olsa keşfetmek yaptı.

<object>.__getattribute__(<string name>)(<params>)

Ben Python 2.66 kullanıyorum

Bu yardımcı olur umarım

Cevap 28/12/2012 saat 17:56
kaynak kullanıcı

oy
0

Bu, bu örneğin ekranı temizlemek sağlayacak basit bir cevaptır. (Windows kullanıyorsanız eğer değiştirmek temizlendikten sonra üstündeki 0 yazdırır eval ve exec ile aşağıda iki örnek, vardır cleariçin clsLinux ve Mac kullanıcıları örneğin olduğu gibi bırakın) sırasıyla veya bunu çalıştırır.

eval("os.system(\"clear\")")
exec("os.system(\"clear\")")
Cevap 28/08/2019 saat 19:46
kaynak kullanıcı

oy
0

Bu soru olarak dinamik bir değişken [kopya] olarak metot adı atama kullanarak bir sınıf içindeki yöntemleri çağırmak nasıl bu bir yineleme olarak işaretlenmiş, burada ilgili Yanıt göndererek ediyorum:

senaryo bir sınıfta bir yöntem dinamik olarak aynı sınıfa başka yöntemi çağırmak istiyorum, ben biraz daha geniş senaryo ve netlik sunuyor orijinal örneğe bazı ayrıntıları ekledi:

class MyClass:
def __init__(self, i):
    self.i = i

def get(self):
    func = getattr(MyClass, 'function{}'.format(self.i))
    func(self, 12)   # This one will work
    # self.func(12)    # But this does NOT work.


def function1(self, p1):
    print('function1: {}'.format(p1))
    # do other stuff

def function2(self, p1):
    print('function2: {}'.format(p1))
    # do other stuff


if __name__ == "__main__":
    class1 = MyClass(1)
    class1.get()
    class2 = MyClass(2)
    class2.get()

Çıkış (Python 3.7.x)

fonksiyonu1: 12

İşlevsiz2: 12

Cevap 26/03/2019 saat 18:15
kaynak kullanıcı

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more