2016-08-02 5 views
0

파이썬에서 클래스를 만들려면 시작하는 몇 가지 코드 변수 이름의 정적 목록어떻게 동적으로 초기화 여기

플랜 B : eval()을 사용하여 함수가 생성하는 코드를 실행할 수 있습니다. 그러나 eval()은 가능한 한 피해야합니다. 여기에서의 도전은 eval()없이 이것을하는 것입니다.

편집 : 질문을 쓰는 동안 나는 해결책을 찾았다. (아래를보십시오.) 아마도 이것은 누군가를 도울 것입니다.

EDIT2 :이 함수는 변경 가능하다는 점을 제외하고 namedtuple()과 같은 것을 만들 때 사용합니다. 당신은 나중에 필드의 사용에 대해 아무것도 언급하지 않는

def objectify(obj_name, fields): 
    """ Create a new object including the __init__() method. """ 

    def __init__(self, *argv): 
     """ Generic initializer for dynamically created classes. """ 
     fields = objectify.fields[self.__class__.__name__] 
     for field, val in zip(fields, argv): 
      setattr(self, field, val) 

    result = type(obj_name, (object,), dict()) 
    result.__init__ = __init__ 

    # Save the list of fields in a static dictionary that is retrieved by class name. 
    objectify.fields[obj_name] = fields 

    return result 

objectify.fields = {}   # A static local variable. 

답변

0

여기에 하나 개의 솔루션입니다. 당신은 단지 __init__에서 그들을 필요로하는 경우에 그들 모두를 저장할 필요가 없습니다

def objectify(name, fields): 
    """ Create a new object including the __init__() method. """ 
    fields = fields[:] 
    def __init__(self, *argv): 
     for name, val in zip(fields, argv): 
      setattr(self, name, val) 

    result = type(name, (object,), dict(__init__=__init__)) 
    return result 

그렇지 않으면, 당신은 메타 클래스 보라 - 즉 정확하게 그들을 위해 유스 케이스입니다.

업데이트 : fields 사본을 작성하면 호출자의 목록을 변경해도 저장된 것에 영향을주지 않습니다. 값은 여전히 ​​바뀔 수 있습니다 ... 모든 것을 확인하기 위해 독자에게 운동으로 남긴 것은 str입니다.

3

:

Point = objectify('point', ['x', 'y']) 
a = Point(1, 2) 
b = Point(2, 3) 
print a.__dict__ 
print b.__dict__ 
+0

이 기능을 사용하는 방법을 설명하기 위해 'EDIT2'를 추가했습니다. 일종의 mutable'namedtuple()'과 같습니다. – ChaimG

+0

그건 내 솔루션을 잘 작동합니다. 추가 저장 장치가 필요 없습니다. – viraptor

+0

귀하의 솔루션을 검증했는데 정확합니다! 왜 이것이 효과가 있는지 궁금합니다. – ChaimG