programing

사전에서 클래스 인스턴스 속성을 생성합니까?

firstcheck 2021. 1. 17. 10:56
반응형

사전에서 클래스 인스턴스 속성을 생성합니까?


CSV에서 가져오고 대략 형식의 데이터를 가져옵니다.

{ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }

필드 이름은 동적입니다. 점에서 (글쎄, 그들은있는 거 동적 더 필드 1과 필드 2 이상이있을 수 있습니다,하지만 난 알고 Field1그리고 Field2항상있을 것입니다.

allMyFields위의 데이터에 속성으로 액세스 할 수 있도록 이 사전을 내 클래스에 전달할 수 있기를 원합니다 .

class allMyFields:
    # I think I need to include these to allow hinting in Komodo. I think.
    self.Field1 = None
    self.Field2 = None

    def __init__(self,dictionary):
        for k,v in dictionary.items():
            self.k = v
            #of course, this doesn't work. I've ended up doing this instead
            #self.data[k] = v
            #but it's not the way I want to access the data.

q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
instance = allMyFields(q)
# Ideally I could do this.
print q.Field1

어떤 제안? 그 이유에 관해서는-코드 힌트를 활용하고 싶습니다. 데이터를 data제가 해왔 던 딕셔너리로 ​​가져 오는 것은 저에게 여유가 없습니다.

(변수 이름은 런타임까지 해결되지 않기 때문에 Komodo에 뼈를 던져야 self.Field1 = None할 것입니다. 충분해야 한다고 생각합니다 .)

그래서-내가 원하는 것을 어떻게합니까? 아니면 잘못 설계된 비 파이썬 트리를 짖고 있습니까?


다음을 사용할 수 있습니다 setattr(주의 : 모든 문자열이 유효한 속성 이름은 아닙니다!) :

>>> class AllMyFields:
...     def __init__(self, dictionary):
...         for k, v in dictionary.items():
...             setattr(self, k, v)
... 
>>> o = AllMyFields({'a': 1, 'b': 2})
>>> o.a
1

편집 : 위 코드와 SilentGhost의 대답 의 차이점을 설명하겠습니다 . 위의 코드 조각은 지정된 사전을 기반으로하는 인스턴스 속성 의 클래스를 만듭니다 . SilentGhost의 코드는 클래스 속성 이 주어진 사전을 기반으로하는 클래스를 생성합니다 .

특정 상황에 따라 이러한 솔루션 중 하나가 더 적합 할 수 있습니다. 하나 이상의 클래스 인스턴스를 만들 수 있습니까? 대답이 하나 인 경우 객체 생성을 완전히 건너 뛰고 유형 만 구성 할 수 있습니다 (따라서 SilentGhost의 대답으로 이동).


>>> q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
>>> q = type('allMyFields', (object,), q)
>>> q.Field1
3000

type여기에 무슨 일이 일어나고 있는지 잘 설명하는 문서 (생성자로 사용 참조).

편집 : 인스턴스 변수가 필요한 경우 다음도 작동합니다.

>>> a = q()             # first instance
>>> a.Field1
3000
>>> a.Field1 = 1
>>> a.Field1
1
>>> q().Field1           # second instance
3000

dict.update수동으로 반복 하는 대신 사용할 수도 있습니다 items( 루핑하는 경우 iteritems더 좋습니다).

class allMyFields(object):
    # note: you cannot (and don't have to) use self here
    Field1 = None
    Field2 = None

    def __init__(self, dictionary):
        self.__dict__.update(dictionary)

q = { 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 }
instance = allMyFields(q)

print instance.Field1      # => 3000
print instance.Field2      # => 6000
print instance.RandomField # => 5000

명명 된 튜플 사용 (Python 2.6) :

>>> from collections import namedtuple

>>> the_dict = {'Field1': 3, 'Field2': 'b', 'foo': 4.9}
>>> fields = ' '.join(the_dict.keys())
>>> AllMyFields = namedtuple('AllMyFields', fields)
>>> instance = AllMyFields(**the_dict)

>>> print instance.Field1, instance.Field2, instance.foo
3 b 4.9

dict키에 대한 속성 조회를 허용 하는 하위 클래스를 만들 수 있습니다.

class AttributeDict(dict):
    def __getattr__(self, name):
        return self[name]

q = AttributeDict({ 'Field1' : 3000, 'Field2' : 6000, 'RandomField' : 5000 })
print q.Field1              
print q.Field2              
print q.RandomField

dict이미 있는 속성 (예 : keys또는 get) 을 찾으려고 하면 해당 dict클래스 속성 (메서드)을 얻을 수 있습니다. 요청한 키가 dict클래스 에 없으면 __getattr__메서드가 호출되어 키 조회를 수행합니다.


예쁜 방법으로 setattr을 사용하십시오. 빠르고 더러운 방법은 인스턴스 내부 사전을 업데이트하는 것입니다.

>>> class A(object):
...    pass
...
>>> a = A()
>>> a.__dict__.update({"foo": 1, "bar": 2})
>>> a.foo
1
>>> a.bar
2
>>>

class SomeClass:
    def __init__(self,
                 property1,
                 property2):
       self.property1 = property1
       self.property2 = property2


property_dict = {'property1': 'value1',
                 'property2': 'value2'}
sc = SomeClass(**property_dict)
print(sc.__dict__)

Or you can try this

class AllMyFields:
    def __init__(self, field1, field2, random_field):
        self.field1 = field1
        self.field2 = field2
        self.random_field = random_field

    @classmethod
    def get_instance(cls, d: dict):
        return cls(**d)


a = AllMyFields.get_instance({'field1': 3000, 'field2': 6000, 'random_field': 5000})
print(a.field1)

enhanced of sub class of dict

recurrence dict works!

class AttributeDict(dict):
    """https://stackoverflow.com/a/1639632/6494418"""

    def __getattr__(self, name):
        return self[name] if not isinstance(self[name], dict) \
            else AttributeDict(self[name])


if __name__ == '__main__':
    d = {"hello": 1, "world": 2, "cat": {"dog": 5}}
    d = AttributeDict(d)
    print(d.cat)
    print(d.cat.dog)
    print(d.cat.items())

    """
    {'dog': 5}
    5
    dict_items([('dog', 5)])
    """

ReferenceURL : https://stackoverflow.com/questions/1639174/creating-class-instance-properties-from-a-dictionary

반응형