programing

기본 클래스에서 파생 클래스를 동적으로 만드는 방법

javamemo 2023. 9. 27. 16:46
반응형

기본 클래스에서 파생 클래스를 동적으로 만드는 방법

예를 들어 다음과 같은 기본 클래스가 있습니다.

class BaseClass(object):
    def __init__(self, classtype):
        self._type = classtype

저는 이 수업에서 몇가지 다른 수업들을 이끌어냅니다. 예를 들어요.

class TestClass(BaseClass):
    def __init__(self):
        super(TestClass, self).__init__('Test')

class SpecialClass(BaseClass):
    def __init__(self):
        super(TestClass, self).__init__('Special')

함수 호출을 통해 새로운 클래스를 현재 범위에 포함시켜 동적으로 클래스를 생성할 수 있는 좋은 파이토닉 방법이 있습니까?

foo(BaseClass, "My")
a = MyClass()
...

가 이것이 왜 에 대한 이기 때문에: 파생된 클래스는 모두 생성자가 이전에 정의되지 않은 여러 인수를 사용하는 차이와 완전히 동일한 내부 구조를 갖습니다.를 들면,면 같은 경우에는MyClass다로 합니다.a로서 가 되는 .TestClass이 깁니다.b그리고.c.

inst1 = MyClass(a=4)
inst2 = MyClass(a=5)
inst3 = TestClass(b=False, c = "test")

그러나 그들은 절대로 수업의 종류를 입력 인수로 사용해서는 안됩니다.

inst1 = BaseClass(classtype = "My", a=4)

이것이 작동되도록 만들었지만 다른 방식, 즉 동적으로 생성된 클래스 개체를 선호합니다.

이 코드 비트를 사용하면 동적 이름과 매개 변수 이름으로 새 클래스를 만들 수 있습니다. 검증__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():
            # here, the argnames variable is the one passed to the
            # ClassFactory call
            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

이름 지정 범위에 동적 이름을 삽입하라는 요청을 받았습니다. 이제 Python에서는 좋은 방법으로 간주되지 않습니다. 코드화 시점에 알려진 변수 이름 또는 데이터가 있습니다. 런타임에 학습된 이름은 "변수"보다 "데이터"가 더 많습니다.

따라서 클래스를 사전에 추가하여 사용할 수 있습니다.

name = "SpecialClass"
classes = {}
classes[name] = ClassFactory(name, params)
instance = classes[name](...)

그리고 디자인이 범위에 포함되어야 할 이름이 꼭 필요한 경우에는 동일한 작업을 수행하되 임의 사전 대신 호출에 의해 반환된 사전을 사용합니다.

name = "SpecialClass"
globals()[name] = ClassFactory(name, params)
instance = SpecialClass(...)

(클래스 팩토리 함수가 호출자의 글로벌 범위에 동적으로 이름을 삽입하는 것은 실제로 가능하지만, 이는 훨씬 더 나쁜 관행이며, Python 구현 간에 호환되지 않습니다.그 방법은 발신자의 실행 프레임을 sys를 통해 얻는 것입니다._getframe(1) 및 해당 프레임의 글로벌 사전에 클래스 이름을 설정합니다.f_globals속성).

업데이트, tl;dr:이 답변은 인기를 끌었지만, 여전히 질문 본문에 매우 구체적입니다.Python에서 "기본 클래스에서 파생된 클래스를 동적으로 만드는 방법"에 대한 일반적인 대답은 다음과 같습니다.type새 클래스 이름 전달, 기본 클래스가 있는 튜플 및__dict__새로운 수업을 위한 본문 - 다음과 같이:

>>> new_class = type("NewClassName", (BaseClass,), {"new_method": lambda self: ...})

갱신하다
이것이 필요한 사람은 누구나 이 프로젝트를 확인해 보아야 합니다. 이 프로젝트는 피클이 일반 물체에 하는 것처럼 수업을 피클로 하고 뜯을 수 있다고 주장하며, 제가 몇 번 테스트를 해본 적이 있습니다.

는 질문과 같이 클래스와 특히 하위 classes을 생성하는 함수입니다.

def set_x(self, value):
    self.x = value

# type() takes as argument the new class name, its base
# classes, and its attributes:
SubClass = type('SubClass', (BaseClass,), {'set_x': set_x})
# (More methods can be put in SubClass, including __init__().)

obj = SubClass()
obj.set_x(42)
print obj.x  # Prints 42
print isinstance(obj, BaseClass)  # True

나의 경우:

inst3 = globals()["SpecialClass"](b=False, c = "test")

동적 속성 값을 가진 클래스를 만들려면 아래 코드를 확인하십시오.NB. 이것은 파이썬 프로그래밍 언어의 코드 조각들입니다.

def create_class(attribute_data, **more_data): # define a function with required attributes
    class ClassCreated(optional extensions): # define class with optional inheritance
          attribute1 = adattribute_data # set class attributes with function parameter
          attribute2 = more_data.get("attribute2")

    return ClassCreated # return the created class

# use class

myclass1 = create_class("hello") # *generates a class*

언급URL : https://stackoverflow.com/questions/15247075/how-can-i-dynamically-create-derived-classes-from-a-base-class

반응형