파이썬에서 런타임에 클래스를 동적으로 만들고 싶습니다.런타임에 클래스를 생성 할 때`type()`보다`exec`를 사용하면 어떤 이점이 있습니까?
예를 들어, 나는 아래의 코드를 복제 할 :
>>> class RefObj(object):
... def __init__(self, ParentClassName):
... print "Created RefObj with ties to %s" % ParentClassName
... class Foo1(object):
... ref_obj = RefObj("Foo1")
... class Foo2(object):
... ref_obj = RefObj("Foo2")
...
Created RefObj with ties to Foo1
Created RefObj with ties to Foo2
>>>
을 ...하지만 나는 FOO1, FOO2, 푸 클래스, 즉 (동적으로 생성 할 : 실행 중에 대신 첫 번째 패스 엮다). 이를 달성하기
한 가지 방법과 같이, type()
함께 :
>>> class RefObj(object):
... def __init__(self, ParentClassName):
... print "Created RefObj with ties to %s" % ParentClassName
... def make_foo_class(index):
... name = "Foo%s" % index
... return type(name, (object,), dict(ref_obj = RefObj(name)))
...
>>> Foo1 = make_foo_class(1)
Created RefObj with ties to Foo1
>>> Foo2 = make_foo_class(2)
Created RefObj with ties to Foo2
>>> type(Foo1()), type(Foo2())
(<class 'Foo1'>, <class 'Foo2'>)
나는 또한과 같이, exec
그것을 얻을 수 있습니다
>>> class RefObj(object):
... def __init__(self, ParentClassName):
... print "Created RefObj with ties to %s" % ParentClassName
... def make_foo_object(index):
... class_template = """class Foo%(index)d(object):
... ref_obj = RefObj("Foo%(index)d")
... """ % dict(index = index)
... global RefObj
... namespace = dict(RefObj = RefObj)
... exec class_template in namespace
... return namespace["Foo%d" % index]
...
>>> Foo1 = make_foo_object(1)
Created RefObj with ties to Foo1
>>> Foo2 = make_foo_object(2)
Created RefObj with ties to Foo2
>>> type(Foo1()), type(Foo2())
(<class 'Foo1'>, <class 'Foo2'>)
exec
의 사용은 잘 앉지 않는다 나와 함께 (이 질문을 읽는 많은 사람들과 함께하지는 않을 것으로 기대하지만) exec
은 정확히 파이썬의 클래스 is implemented (this line 참조). 또한이 계열의 개발자 (Raymond Hettinger)가 exec
here을 사용하는 것을 방어해야합니다. 이 방어에서는 "은 명명 된 튜플의 핵심 기능으로 손으로 작성한 클래스과 정확히 동일합니다. type()
의 사용이 exec
만큼 좋지 않음을 나타낼 수 있습니다. ...
차이가 있습니까? 왜 exec
대 type()
대 사용해야합니까?
나는 대답은 두 가지가 동일한 지있을 수 있습니다 예상과는 namedtuple
구현은 그것을 통해 후추를 namedtuple 변수를 많이 가지고 단순히 모든 방법은 코드를 다루기 얻을 제작을 위해 함께이 일을하는 것은 동적으로 클로저를 생성 ,하지만 더 많은 것을 알고 싶습니다.
불편한 점은 exec
입니다. 신뢰할 수없는 당사자가 악의적 인 코드를 삽입하는 방법이 없다면 신경 써야합니다.
http://blog.ccpgames.com/kristjan/2011/05/28/namedtuple-and-exec/에서도이 문제에 대해 좋은 토론이 진행되었으며 이에 대한 또 다른 좋은 블로그 게시물이있었습니다. 나는 지금 보지 않는다. 상황에서'type'이 문제가되는 이유를 제시하지 않았으므로'type'이 작동한다는 것을 알고 있기 때문에 왜'exec '에 신경 쓰는지 모르겠습니다. (호기심을 제외하고는 분명히). – agf
@agf - 좋은 링크, 고마워! 두 가지 접근법이 모두 작동하기 때문에 처음에는'type'에 문제가 없었습니다. 차이점에 대해서 궁금해서'namedtuple'에서'exec' 사용 이유를 이해하려고했습니다. 하지만 클래스/함수 시그니처 인수는 훌륭합니다. 필자는 종종 [decorator] (http://pypi.python.org/pypi/decorator) 패키지를 사용해야하는 데코레이터 문제가 있습니다. – Russ
역동적 인 클래스 생성에 대한 필요성을 뒷받침 할 수 있습니까? 아니면 단지 호기심입니까? – dhill