반응형
이름으로 Python 메서드 호출
문자열에 객체와 메서드 이름이있는 경우 메서드를 어떻게 호출 할 수 있습니까?
class Foo:
def bar1(self):
print 1
def bar2(self):
print 2
def callMethod(o, name):
???
f = Foo()
callMethod(f, "bar1")
쉬운 것 :
class Foo:
def bar1(self):
print 1
def bar2(self):
print 2
def callMethod(o, name):
getattr(o, name)()
f = Foo()
callMethod(f, "bar1")
getattr 살펴보기
setattr 을 사용 하여 이름으로 클래스 속성을 설정할 수도 있습니다 .
비슷한 질문이 있었고 인스턴스 메서드를 참조로 호출하고 싶었습니다. 내가 찾은 재미있는 것들은 다음과 같습니다.
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
파이썬은 놀랍습니다!
getattr(globals()['Foo'](), 'bar1')()
getattr(globals()['Foo'](), 'bar2')()
Foo를 먼저 인스턴스화 할 필요가 없습니다!
def callmethod(cls, mtd_name):
method = getattr(cls, mtd_name)
method()
다음은 Python 데코레이터를 사용하는보다 일반화 된 버전입니다. 짧거나 긴 이름으로 전화를 걸 수 있습니다. 짧고 긴 하위 명령으로 CLI를 구현할 때 유용하다는 것을 알았습니다.
파이썬 데코레이터는 훌륭합니다. Bruce Eckel (Thinking in Java)은 여기에서 Python 데코레이터를 아름답게 설명합니다.
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')
참고URL : https://stackoverflow.com/questions/3521715/call-a-python-method-by-name
반응형
'program tip' 카테고리의 다른 글
ggplot2 테마 옵션 목록? (0) | 2020.11.15 |
---|---|
java.lang.NoSuchMethodError 메시지 해석 (0) | 2020.11.15 |
사용자가 열 머리글을 클릭 할 때 DataGridView 정렬을 활성화하는 방법은 무엇입니까? (0) | 2020.11.15 |
파이썬에서는 왜 인쇄 대신 로깅을 사용합니까? (0) | 2020.11.15 |
KnockoutJS에서 $ data 변수의 기원과 목적은 무엇입니까? (0) | 2020.11.15 |