질문자 :ricree
파이썬 프로그램에서 함수 이름이 있는 문자열이 주어진 함수를 호출하는 가장 좋은 방법은 무엇입니까? 예를 들어 모듈 foo
가 있고 내용이 "bar"
인 문자열이 있다고 가정해 보겠습니다. foo.bar()
를 호출하는 가장 좋은 방법은 무엇입니까?
함수의 반환 값을 eval
하므로 eval 만 사용하지 않습니다. eval
을 사용하여 해당 함수 호출의 결과를 반환하는 임시 함수를 정의하는 방법을 알아냈지만 더 우아한 방법이 있기를 바랍니다.
메소드 bar
모듈 foo
를 가정합니다.
import foo method_to_call = getattr(foo, 'bar') result = method_to_call()
2행과 3행을 다음과 같이 단축할 수 있습니다.
result = getattr(foo, 'bar')()
그것이 당신의 사용 사례에 더 의미가 있다면.
클래스 인스턴스 바인딩 메서드, 모듈 수준 메서드, 클래스 메서드에 대해 이러한 방식으로 getattr
을 사용할 수 있습니다. 목록은 계속됩니다.
Patrick Johnmeyerlocals()["myfunction"]()
또는
globals()["myfunction"]()
locals 는 현재 로컬 기호 테이블이 있는 사전을 반환합니다. globals 는 전역 기호 테이블이 있는 사전을 반환합니다.
sastaninPatrick의 솔루션이 아마도 가장 깨끗할 것입니다. 모듈도 동적으로 선택해야 하는 경우 다음과 같이 가져올 수 있습니다.
module = __import__('foo') func = getattr(module, 'bar') func()
HS.단순한 기여일 뿐입니다. 인스턴스화해야 하는 클래스가 동일한 파일에 있는 경우 다음과 같이 사용할 수 있습니다.
# 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()
예를 들어:
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')
그리고 클래스가 아닌 경우:
def sampleFunc(arg): print('you called sampleFunc({})'.format(arg)) globals()['sampleFunc']('sample arg')
Sourcegeek함수에 대한 완전한 파이썬 경로가 있는 문자열이 주어지면 다음은 해당 함수의 결과를 얻는 방법입니다.
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()
ferrouswheelPython 프로그래밍 FAQ 에 따른 가장 좋은 대답은 다음과 같습니다.
functions = {'myfoo': foo.bar} mystring = 'myfoo' if mystring in functions: functions[mystring]()
이 기술의 주요 이점은 문자열이 함수 이름과 일치할 필요가 없다는 것입니다. 이것은 또한 케이스 구성을 에뮬레이트하는 데 사용되는 기본 기술입니다.
user3946687그 누구도 바라지 않았던 대답 (나는 바래)
행동과 같은 평가
getattr(locals().get("foo") or globals().get("foo"), "bar")()
자동 가져오기를 추가하지 않는 이유
getattr( locals().get("foo") or globals().get("foo") or __import__("foo"), "bar")()
확인하려는 추가 사전이 있는 경우
getattr(next((x for x in (f("foo") for f in [locals().get, globals().get, self.__dict__.get, __import__]) if x)), "bar")()
우리는 더 깊이 갈 필요가 있습니다
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")()
00500005그 가치를 위해 함수(또는 클래스) 이름과 앱 이름을 문자열로 전달해야 하는 경우 다음을 수행할 수 있습니다.
myFnName = "MyFn" myAppName = "MyApp" app = sys.modules[myAppName] fn = getattr(app,myFnName)
trubliphone이 시도. 이것은 여전히 eval을 사용하지만 현재 컨텍스트에서 함수를 호출 하는 데만 사용합니다. 그런 다음 원하는대로 사용할 실제 기능이 있습니다.
이것의 주요 이점은 함수를 호출하는 시점에서 평가 관련 오류가 발생한다는 것입니다. 전화 할 때 그리고 당신은 단지 기능 관련 오류를 얻을 것이다.
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)
tvt173제안된 것 중 어느 것도 도움이 되지 않았습니다. 나는 이것을 발견했다.
<object>.__getattribute__(<string name>)(<params>)
나는 파이썬 2.66을 사용하고 있습니다
도움이 되었기를 바랍니다
Natdrip이 질문 과 같이 중복으로 표시된 변수 [중복]에 메서드 이름 할당을 사용하여 클래스 내에서 메서드를 동적으로 호출하는 방법에 대해 여기에 관련 답변을 게시하고 있습니다.
시나리오는 클래스의 메서드가 동일한 클래스의 다른 메서드를 동적으로 호출하려는 것입니다. 더 넓은 시나리오와 명확성을 제공하는 원본 예제에 몇 가지 세부 정보를 추가했습니다.
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()
출력(파이썬 3.7.x)
기능1: 12
기능2: 12
Serjikgetattr() 은 우아하고(약 7배 더 빠름) 메서드이지만 eval 을 사용하여 x = eval('foo.bar')()
처럼 우아한 함수(로컬, 클래스 메서드, 모듈)에서 반환 값을 얻을 수 있습니다. 그리고 일부 오류 처리를 구현하면 매우 안전합니다(getattr에 동일한 원칙을 사용할 수 있음). 모듈 가져오기 및 클래스가 있는 예:
# import module, call module function, pass parameters and print retured value with eval(): import random bar = 'random.randint' randint = eval(bar)(0,100) print(randint) # will print random int from <0;100) # also class method returning (or not) value(s) can be used with eval: class Say: def say(something='nothing'): return something bar = 'Say.say' print(eval(bar)('nice to meet you too')) # will print 'nice to meet you'
모듈이나 클래스가 존재하지 않으면(오타 또는 더 나은 것) NameError가 발생합니다. 함수가 존재하지 않으면 AttributeError가 발생합니다. 이것은 오류를 처리하는 데 사용할 수 있습니다.
# try/except block can be used to catch both errors try: eval('Say.talk')() # raises AttributeError because function does not exist eval('Says.say')() # raises NameError because the class does not exist # or the same with getattr: getattr(Say, 'talk')() # raises AttributeError getattr(Says, 'say')() # raises NameError except AttributeError: # do domething or just... print('Function does not exist') except NameError: # do domething or just... print('Module does not exist')
Lukasgetattr
은 개체에서 이름으로 메서드를 호출합니다. 그러나 이 객체는 호출하는 클래스의 부모여야 합니다. 부모 클래스는 super(self.__class__, self)
class Base: def call_base(func): """This does not work""" def new_func(self, *args, **kwargs): name = func.__name__ getattr(super(self.__class__, self), name)(*args, **kwargs) return new_func def f(self, *args): print(f"BASE method invoked.") def g(self, *args): print(f"BASE method invoked.") class Inherit(Base): @Base.call_base def f(self, *args): """function body will be ignored by the decorator.""" pass @Base.call_base def g(self, *args): """function body will be ignored by the decorator.""" pass Inherit().f() # The goal is to print "BASE method invoked."
정도유나는 이전에 문자열을 함수로 변환하는 유사한 문제에 직면하고 있습니다. 하지만 이 코드를 즉시 실행하고 싶지 않기 때문에 eval()
또는 ast.literal_eval()
사용할 수 없습니다.
"foo.bar"
라는 문자열이 있고 문자열 x
에 할당하고 싶습니다. 즉 x()
ON DEMAND로 함수를 호출할 수 있습니다.
내 코드는 다음과 같습니다.
str_to_convert = "foo.bar" exec(f"x = {str_to_convert}") x()
귀하의 질문에 대해서는 모듈 이름 foo
및 .
다음과 같이 {}
전에:
str_to_convert = "bar" exec(f"x = foo.{str_to_convert}") x()
경고!!! eval()
또는 exec()
는 위험한 방법이므로 안전성을 확인해야 합니다. 경고!!! eval()
또는 exec()
는 위험한 방법이므로 안전성을 확인해야 합니다. 경고!!! eval()
또는 exec()
는 위험한 방법이므로 안전성을 확인해야 합니다.
Bowen 404__getattribute__
메서드를 사용할 수 있습니다. 목록 메서드 이름 문자열이 있는 다음 예를 참조하세요.
func_name = 'reverse' l = [1, 2, 3, 4] print(l) >> [1, 2, 3, 4] l.__getattribute__(func_name)() print(l) >> [4, 3, 2, 1]
Aliakbar Ahmadi이것은 간단한 대답입니다. 예를 들어 화면을 지울 수 있습니다. 아래에는 eval 및 exec의 두 가지 예가 있습니다. 청소 후 맨 위에 0을 인쇄하거나(Windows를 사용하는 경우 clear
를 cls
변경하고 Linux 및 Mac 사용자는 그대로 둡니다) 각각 실행합니다.
eval("os.system(\"clear\")") exec("os.system(\"clear\")")
Number File출처 : http:www.stackoverflow.com/questions/3061/calling-a-function-of-a-module-by-using-its-name-a-string