이 코드를 사용하면 동적 이름과 매개 변수 이름으로 새 클래스를 만들 수 있습니다. 의 매개 변수 확인은 __init__
알 수없는 매개 변수를 허용하지 않습니다. 유형과 같은 다른 확인이 필요하거나 필수 항목 인 경우 여기에 논리를 추가하면됩니다.
class BaseClass(object):
def __init__(self, classtype):
self._type = classtype
def ClassFactory(name, argnames, BaseClass=BaseClass):
def __init__(self, **kwargs):
for key, value in kwargs.items():
if key not in argnames:
raise TypeError("Argument %s not valid for %s"
% (key, self.__class__.__name__))
setattr(self, key, value)
BaseClass.__init__(self, name[:-len("Class")])
newclass = type(name, (BaseClass,),{"__init__": __init__})
return newclass
그리고 이것은 다음과 같이 작동합니다.
>>> SpecialClass = ClassFactory("SpecialClass", "a b c".split())
>>> s = SpecialClass(a=2)
>>> s.a
2
>>> s2 = SpecialClass(d=3)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 8, in __init__
TypeError: Argument d not valid for SpecialClass
지금 - 당신이 명명 범위에 동적 이름을 삽입을 요구하고 볼 것을 당신도 변수 코딩시에 알려진 이름, 또는 데이터가 - - 파이썬에서 좋은 연습으로 간주되지 않으며, 런타임에서 배운 이름은 "더 있습니다 데이터 "보다"변수 "-
따라서 클래스를 사전에 추가하고 거기에서 사용할 수 있습니다.
name = "SpecialClass"
classes = {}
classes[name] = ClassFactory(name, params)
instance = classes[name](...)
그리고 디자인에 반드시 이름이 범위에 포함되어야하는 경우 똑같이 수행하되 globals()
임의의 사전 대신 호출에서 반환 된 사전을 사용하십시오 .
name = "SpecialClass"
globals()[name] = ClassFactory(name, params)
instance = SpecialClass(...)
(실제로 클래스 팩토리 함수가 호출자의 전역 범위에 이름을 동적으로 삽입하는 것이 가능할 수 있습니다.하지만 이는 더 나쁜 관행이며 Python 구현간에 호환되지 않습니다. 그렇게하는 방법은 호출자의 이름을 가져 오는 것입니다. 실행 프레임, sys._getframe (1)을 통해 프레임의 전역 사전에 클래스 이름을 f_globals
속성으로 설정).
update, tl; dr : 이 답변은 인기를 얻었지만 여전히 질문 본문에 매우 구체적입니다.
Python에서 "기본 클래스에서 파생 클래스를 동적으로 생성" 하는 방법에 대한 일반적인 대답
은 다음과 type
같이 새 클래스 이름, 기본 클래스 가 있는 튜플 및 __dict__
새 클래스 의 본문 을 전달 하는 간단한 호출입니다 .
>>> new_class = type("NewClassName", (BaseClass,), {"new_method": lambda self: ...})
업데이트
가 필요한 사람은 누구나 dill 프로젝트를 확인해야합니다. 피클이 일반 객체에 수행하는 것처럼 클래스를 피클 및 언 피클 할 수 있다고 주장하며 일부 테스트에서 그에 대해 살았습니다.
a
항상있을 것입니다MyClass
및TestClass
을하지 않습니다a
? 3 개의 인수를 모두 선언하지 않고 모두BaseClass.__init__()
기본값으로 설정하는 이유는 무엇None
입니까?def __init__(self, a=None, b=None, C=None)
?