딕트와 같은 역할을 하는 파이썬 클래스
다음과 같이 동작하는 사용자 지정 클래스를 작성합니다.dict
그래서, 저는 상속을 받고 있습니다.dict
.
하지만 제 질문은 개인 정보를 생성해야 합니까?dict
나의 회원__init__()
방법?나는 이미 그것을 가지고 있기 때문에 이것의 요점을 이해하지 못합니다.dict
내가 단순히 상속받은 행동.dict
.
상속 스니펫의 대부분이 아래와 같은 이유를 지적할 수 있는 사람이 있습니까?
class CustomDictOne(dict):
def __init__(self):
self._mydict = {}
# other methods follow
더 단순한 대신에...
class CustomDictTwo(dict):
def __init__(self):
# initialize my other stuff here ...
# other methods follow
사실, 이 질문에 대한 답은 사용자가 사전에 직접 액세스할 수 없도록 하는 것이라고 생각합니다(즉, 사용자가 제공한 액세스 방법을 사용해야 함).
그러나 어레이 액세스 연산자는 어떻게 됩니까?[]
어떻게 구현할 수 있을까요?지금까지, 나는 그것을 무시하는 방법을 보여주는 예를 본 적이 없습니다.[]
교환입니다.
그래서 만약에[]
사용자 지정 클래스에 액세스 기능이 제공되지 않습니다. 상속된 기본 메서드가 다른 사전에서 작동합니까?
Python 상속에 대한 이해를 테스트하기 위해 다음 스니펫을 시도했습니다.
class myDict(dict):
def __init__(self):
self._dict = {}
def add(self, id, val):
self._dict[id] = val
md = myDict()
md.add('id', 123)
print md[id]
다음 오류가 발생했습니다.
키 오류: <내장 함수 ID>
위의 코드에 무슨 문제가 있습니까?
수업을 어떻게 수정myDict
이렇게 코드를 쓸 수 있게요?
md = myDict()
md['id'] = 123
[편집]
저는 제가 책상에서 도망치기 전에 했던 어리석은 실수를 없애기 위해 위의 코드 샘플을 편집했습니다.오타였어요 (오류 메시지에서 발견했어야 했어요)
class Mapping(dict):
def __setitem__(self, key, item):
self.__dict__[key] = item
def __getitem__(self, key):
return self.__dict__[key]
def __repr__(self):
return repr(self.__dict__)
def __len__(self):
return len(self.__dict__)
def __delitem__(self, key):
del self.__dict__[key]
def clear(self):
return self.__dict__.clear()
def copy(self):
return self.__dict__.copy()
def has_key(self, k):
return k in self.__dict__
def update(self, *args, **kwargs):
return self.__dict__.update(*args, **kwargs)
def keys(self):
return self.__dict__.keys()
def values(self):
return self.__dict__.values()
def items(self):
return self.__dict__.items()
def pop(self, *args):
return self.__dict__.pop(*args)
def __cmp__(self, dict_):
return self.__cmp__(self.__dict__, dict_)
def __contains__(self, item):
return item in self.__dict__
def __iter__(self):
return iter(self.__dict__)
def __unicode__(self):
return unicode(repr(self.__dict__))
o = Mapping()
o.foo = "bar"
o['lumberjack'] = 'foo'
o.update({'a': 'b'}, c=44)
print 'lumberjack' in o
print o
In [187]: run mapping.py
True
{'a': 'b', 'lumberjack': 'foo', 'foo': 'bar', 'c': 44}
이것처럼.
class CustomDictOne(dict):
def __init__(self,*arg,**kw):
super(CustomDictOne, self).__init__(*arg, **kw)
이제 다음과 같은 기본 제공 기능을 사용할 수 있습니다.dict.get()
~하듯이self.get()
.
숨겨진 항목을 포장할 필요가 없습니다.self._dict
당신의 수업은 이미 받아쓰기입니다.
용기 유형 에뮬레이션에 대한 설명서를 확인합니다.사용자의 경우 첫 번째 매개 변수는add
그래야 한다self
.
이것이 저의 최선의 해결책입니다.저는 이것을 여러 번번이.
class DictLikeClass:
...
def __getitem__(self, key):
return getattr(self, key)
def __setitem__(self, key, value):
setattr(self, key, value)
...
다음과 같이 사용할 수 있습니다.
>>> d = DictLikeClass()
>>> d["key"] = "value"
>>> print(d["key"])
Python 표준 라이브러리의 UserDict는 이러한 목적으로 설계되었습니다.
대체 솔루션은 다음과 같습니다.
class AttrDict(dict):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.__dict__ = self
a = AttrDict()
a.a = 1
a.b = 2
다음과 같은 역할을 하는 파이썬 클래스
dict
이거 왜 이래요?
상속 스니펫의 대부분이 아래와 같은 이유를 지적할 수 있는 사람이 있습니까?
class CustomDictOne(dict):
def __init__(self):
self._mydict = {}
아마도 dict에서 상속해야 할 충분한 이유가 있을 것입니다(이미 하나를 전달하고 있고 더 구체적인 종류의 dict를 원할 것입니다). 그리고 위임할 다른 dict를 인스턴스화해야 할 충분한 이유가 있을 것입니다(이 클래스의 인스턴스당 두 개의 dict를 인스턴스화할 것이기 때문입니다).하지만 그것은 틀리게 들리지 않나요?
저는 이 사용 사례에 직접 부딪힌 적이 없습니다.저는 당신이 타자가 가능한 딕트를 사용하는 딕트를 타이핑하는 아이디어를 좋아합니다.하지만 그런 경우에 저는 입력된 클래스 속성에 대한 아이디어를 훨씬 더 좋아합니다. 그리고 딕트의 요점은 해시 가능한 유형의 키와 값을 제공할 수 있다는 것입니다.
그렇다면 왜 우리는 이런 스니펫을 볼 수 있을까요?저는 개인적으로 그것이 수정되지 않고 시간이 지남에 따라 지속된 쉽게 만들어진 실수라고 생각합니다.
나는 차라리 이 스니펫에서 상속을 통한 코드 재사용을 보여주기 위해 이것을 보고 싶습니다.
class AlternativeOne(dict):
__slots__ = ()
def __init__(self):
super().__init__()
# other init code here
# new methods implemented here
또는 딕트의 동작을 다시 정의하려면 다음과 같이 하십시오.
from collections.abc import MutableMapping
class AlternativeTwo(MutableMapping):
__slots__ = '_mydict'
def __init__(self):
self._mydict = {}
# other init code here
# dict methods reimplemented and new methods implemented here
요청에 따라 - 딕트 하위 클래스에 슬롯을 추가합니다.
슬롯을 추가해야 하는 이유기본 제공dict
인스턴스에 임의 특성이 없습니다.
>>> d = dict()
>>> d.foo = 'bar'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'dict' object has no attribute 'foo'
만약 우리가 이 답변에서 대부분이 하는 방식으로 하위 클래스를 만든다면, 우리는 동일한 동작을 얻지 못한다는 것을 알 수 있습니다. 왜냐하면 우리는 다음과 같은 행동을 할 것이기 때문입니다.__dict__
속성으로 인해 딕트가 잠재적으로 최대 두 배의 공간을 차지합니다.
my_dict(dict):
"""my subclass of dict"""
md = my_dict()
md.foo = 'bar'
위와 같은 오류가 발생하지 않으므로 위의 클래스는 실제로 "와 같은" 행동을 하지 않습니다.dict
."
빈 슬롯을 지정하여 딕트처럼 동작할 수 있습니다.
class my_dict(dict):
__slots__ = ()
md = my_dict()
이제 임의 속성을 사용하려고 하면 실패합니다.
>>> md.foo = 'bar'
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'my_dict' object has no attribute 'foo'
그리고 이 파이썬 클래스는 마치dict
.
슬롯 사용 방법 및 사용 이유에 대한 자세한 내용은 Q&A: Usage of __slots_?를 참조하십시오.
어디에서도 이것에 대한 올바른 답을 찾을 수 없습니다.
class MyClass(dict):
def __init__(self, a_property):
self[a_property] = a_property
이 정말 할로▁your다▁all▁own▁define를 정의하는 것입니다.__init__
그것이 정말로 그것이 있는 전부입니다.
또 다른 예(조금 더 복잡함):
class MyClass(dict):
def __init__(self, planet):
self[planet] = planet
info = self.do_something_that_returns_a_dict()
if info:
for k, v in info.items():
self[k] = v
def do_something_that_returns_a_dict(self):
return {"mercury": "venus", "mars": "jupiter"}
이 마지막 예는 어떤 종류의 논리를 포함하고 싶을 때 유용합니다.
어쨌든...요컨대class GiveYourClassAName(dict)
당신의 학급이 받아쓰기처럼 행동하게 만들기에 충분합니다.사자가수모받아기쓰든는하에 대해 수행하는 self
일반적인 받아쓰기와 같을 것입니다.
이 코드 덩어리의 문제:
class myDict(dict):
def __init__(self):
self._dict = {}
def add(id, val):
self._dict[id] = val
md = myDict()
md.add('id', 123)
...'추가' 메서드(...그리고 클래스의 멤버가 되고 싶은 모든 메서드)는 다음과 같이 명시적인 '자체'를 첫 번째 인수로 선언해야 합니다.
def add(self, 'id', 23):
키별로 항목에 액세스하기 위해 연산자 오버로드를 구현하려면 문서에서 마법 방법을 찾습니다.__getitem__
그리고.__setitem__
.
Python은 Duck Typing을 사용하기 때문에 언어의 dict 클래스에서 사용자 지정 dict 클래스를 파생할 이유가 없을 수 있습니다. 사용자가 무엇을 하려고 하는지 더 자세히 알지 못하는 경우(예: 이 클래스의 인스턴스를 다음 코드로 전달해야 하는 경우).isinstance(MyDict(), dict) == True
), 당신은 당신의 수업을 충분히 받아쓰기처럼 만드는 API를 구현하고 거기서 멈추는 것이 더 나을 수도 있습니다.
Python 를 들어, Python에서 상속하지 마십시오.update
using 않하는방법지사용방법.__setitem__
최적화를 위해 많은 일을 합니다.UserDict를 사용합니다.
from collections import UserDict
class MyDict(UserDict):
def __delitem__(self, key):
pass
def __setitem__(self, key, value):
pass
언급URL : https://stackoverflow.com/questions/4014621/a-python-class-that-acts-like-dict
'programing' 카테고리의 다른 글
프로그램의 단일 인스턴스만 실행 중인지 확인 (0) | 2023.07.16 |
---|---|
mongoose를 사용하여 MongoDB에서 대량 업그레이드 (0) | 2023.07.16 |
오리진이 0에서 시작하도록 강제 적용 (0) | 2023.07.16 |
DBef로 $lookup하는 Mongo 방법 (0) | 2023.07.16 |
SQL Server 2008 DateTimeOffset을 DateTime으로 변환하는 방법 (0) | 2023.07.16 |