Oto bardziej uogólniona wersja wykorzystująca dekoratory Pythona. Możesz zadzwonić, używając krótkiej lub długiej nazwy. Znalazłem to przydatne podczas implementowania CLI z krótkimi i długimi poleceniami podrzędnymi.
Dekoratory Pythona są wspaniałe. Bruce Eckel (Thinking in Java) pięknie opisuje tutaj dekoratory Pythona.
Odpowiedzi:
Użyj wbudowanej
getattr()
funkcji:class Foo: def bar1(self): print(1) def bar2(self): print(2) def call_method(o, name): return getattr(o, name)() f = Foo() call_method(f, "bar1") # prints 1
Możesz również użyć
setattr()
do ustawiania atrybutów klas według nazw.źródło
C-f
Miałem podobne pytanie, chciałem wywołać metodę instancji przez odniesienie. Oto zabawne rzeczy, które znalazłem:
instance_of_foo=Foo() method_ref=getattr(Foo, 'bar') method_ref(instance_of_foo) # instance_of_foo becomes self instance_method_ref=getattr(instance_of_foo, 'bar') instance_method_ref() # instance_of_foo already bound into reference
Python jest niesamowity!
źródło
getattr(globals()['Foo'](), 'bar1')() getattr(globals()['Foo'](), 'bar2')()
Nie musisz najpierw tworzyć instancji Foo!
źródło
foo
nie ma go w świecie globalnym?Foo
. ;)def callmethod(cls, mtd_name): method = getattr(cls, mtd_name) method()
źródło
Oto bardziej uogólniona wersja wykorzystująca dekoratory Pythona. Możesz zadzwonić, używając krótkiej lub długiej nazwy. Znalazłem to przydatne podczas implementowania CLI z krótkimi i długimi poleceniami podrzędnymi.
Dekoratory Pythona są wspaniałe. Bruce Eckel (Thinking in Java) pięknie opisuje tutaj dekoratory Pythona.
http://www.artima.com/weblogs/viewpost.jsp?thread=240808 http://www.artima.com/weblogs/viewpost.jsp?thread=240845
#!/usr/bin/env python2 from functools import wraps class CommandInfo(object): cmds = [] def __init__(self, shortname, longname, func): self.shortname = shortname self.longname = longname self.func = func class CommandDispatch(object): def __init__(self, shortname, longname): self.shortname = shortname self.longname = longname def __call__(self, func): print("hello from CommandDispatch's __call__") @wraps(func) def wrapped_func(wself, *args, **kwargs): print('hello from wrapped_func, args:{0}, kwargs: {1}'.format(args, kwargs)) func(wself, *args, **kwargs) ci = CommandInfo ci.cmds += [ci(shortname=self.shortname, longname=self.longname, func=func)] return wrapped_func @staticmethod def func(name): print('hello from CommandDispatch.func') for ci in CommandInfo.cmds: if ci.shortname == name or ci.longname == name: return ci.func raise RuntimeError('unknown command') @CommandDispatch(shortname='co', longname='commit') def commit(msg): print('commit msg: {}'.format(msg)) commit('sample commit msg') # Normal call by function name cd = CommandDispatch short_f = cd.func(name='co') # Call by shortname short_f('short sample commit msg') long_f = cd.func(name='commit') # Call by longname long_f('long sample commit msg') class A(object): @CommandDispatch(shortname='Aa', longname='classAmethoda') def a(self, msg): print('A.a called, msg: {}'.format(msg)) a = A() short_fA = cd.func(name='Aa') short_fA(a, 'short A.a msg') long_fA = cd.func(name='classAmethoda') long_fA(a, 'short A.a msg')
źródło