컨테이너 객체(Python)에 __iter__(자체)를 구현하는 방법
사용자 정의 컨테이너 개체를 작성했습니다.
이 페이지에 따르면 이 방법을 내 객체에 구현해야 합니다.
__iter__(self)
그러나 Python 참조 매뉴얼의 Iterator Types에 대한 링크를 추적한 결과, 사용자 자신의 유형을 구현하는 방법에 대한 예가 제공되지 않았습니다.
누가 이 방법을 보여주는 스니펫(또는 리소스에 대한 링크)을 게시할 수 있습니까?
제가 쓰고 있는 컨테이너는 지도입니다(즉, 고유한 키로 값을 저장합니다).딕트는 다음과 같이 반복할 수 있습니다.
for k, v in mydict.items()
이 경우 반복기에서 두 개의 요소(튜플?)를 반환할 수 있어야 합니다.이러한 반복기를 구현하는 방법은 여전히 명확하지 않습니다(친절하게 제공된 몇 가지 답변에도 불구하고).누가 지도와 같은 컨테이너 객체에 대한 반복기를 구현하는 방법에 대해 좀 더 설명해 주시겠습니까?(즉, 딕트처럼 작동하는 사용자 지정 클래스)?
저는 보통 발전기 기능을 사용합니다.수율 문을 사용할 때마다 시퀀스에 항목이 추가됩니다.
다음은 5개를 생성하는 반복기를 생성하고 some_list의 모든 항목을 생성합니다.
def __iter__(self):
yield 5
yield from some_list
Python 3.3 이전 버전은 존재하지 않았으므로 다음을 수행해야 합니다.
def __iter__(self):
yield 5
for x in some_list:
yield x
다른 옵션은 여기에 문서화된 것처럼 '수집 모듈에서 적절한 추상 기본 클래스를 상속하는 것입니다.
컨테이너가 자체 반복기인 경우 다음에서 상속할 수 있습니다.collections.Iterator
다음을 구현하기만 하면 됩니다.next
그럼 방법.
예는 다음과 같습니다.
>>> from collections import Iterator
>>> class MyContainer(Iterator):
... def __init__(self, *data):
... self.data = list(data)
... def next(self):
... if not self.data:
... raise StopIteration
... return self.data.pop()
...
...
...
>>> c = MyContainer(1, "two", 3, 4.0)
>>> for i in c:
... print i
...
...
4.0
3
two
1
당신이 보고 있는 동안.collections
모듈, 상속 고려Sequence
,Mapping
또는 다른 추상 기본 클래스가 더 적절할 경우.다음은 다음의 예입니다.Sequence
하위 클래스:
>>> from collections import Sequence
>>> class MyContainer(Sequence):
... def __init__(self, *data):
... self.data = list(data)
... def __getitem__(self, index):
... return self.data[index]
... def __len__(self):
... return len(self.data)
...
...
...
>>> c = MyContainer(1, "two", 3, 4.0)
>>> for i in c:
... print i
...
...
1
two
3
4.0
NB: 글렌 메이너드 씨 덕분에 반복기와 반복기가 아닌 반복기의 차이를 명확히 할 필요가 있었습니다.
python의 "iterable interface"는 두 가지 방법으로 구성됩니다.__next__()
그리고.__iter__()
.그__next__
함수는 반복자 동작을 정의하기 때문에 가장 중요합니다. 즉, 함수는 다음에 반환해야 할 값을 결정합니다.__iter__()
메소드는 반복의 시작점을 재설정하는 데 사용됩니다.종종, 당신은 그것을 발견할 것입니다.__iter__()
다음과 같은 경우에는 그냥 자신을 돌아볼 수 있습니다.__init__()
시작점을 설정하는 데 사용됩니다.
"itable interface"를 구현하고 임의의 시퀀스 클래스에서 임의의 인스턴스에 대한 반복기를 정의하는 클래스 역을 정의하려면 다음 코드를 참조하십시오.__next__()
메서드는 시퀀스의 끝에서 시작하고 시퀀스의 역순으로 값을 반환합니다. interface는 " 퀀스인를이스"를 .__len__()
a 리고a.__getitem__()
방법.
class Reverse:
"""Iterator for looping over a sequence backwards."""
def __init__(self, seq):
self.data = seq
self.index = len(seq)
def __iter__(self):
return self
def __next__(self):
if self.index == 0:
raise StopIteration
self.index = self.index - 1
return self.data[self.index]
>>> rev = Reverse('spam')
>>> next(rev) # note no need to call iter()
'm'
>>> nums = Reverse(range(1,10))
>>> next(nums)
9
통보__iter__()
이미 다음 () 방법(generator▁the 객체)을 정의한 경우에는 자신을 반환합니다.
다음은 발전기의 더미 예입니다.
class Test(object):
def __init__(self, data):
self.data = data
def next(self):
if not self.data:
raise StopIteration
return self.data.pop()
def __iter__(self):
return self
그렇지만__iter__()
다음과 같이 사용할 수도 있습니다. http://mail.python.org/pipermail/tutor/2006-January/044455.html
개체에 개체의 반복자를 바인딩할 데이터 집합이 포함된 경우 커닝하여 다음 작업을 수행할 수 있습니다.
>>> class foo:
def __init__(self, *params):
self.data = params
def __iter__(self):
if hasattr(self.data[0], "__iter__"):
return self.data[0].__iter__()
return self.data.__iter__()
>>> d=foo(6,7,3,8, "ads", 6)
>>> for i in d:
print i
6
7
3
8
ads
6
매핑에 대한 질문에 답하기: 제공된 정보__iter__
매핑 키 위에 반복해야 합니다.다음은 매핑을 만드는 간단한 예입니다.x -> x * x
ABC 매핑을 확장하는 Python3에서 작동합니다.
import collections.abc
class MyMap(collections.abc.Mapping):
def __init__(self, n):
self.n = n
def __getitem__(self, key): # given a key, return it's value
if 0 <= key < self.n:
return key * key
else:
raise KeyError('Invalid key')
def __iter__(self): # iterate over all keys
for x in range(self.n):
yield x
def __len__(self):
return self.n
m = MyMap(5)
for k, v in m.items():
print(k, '->', v)
# 0 -> 0
# 1 -> 1
# 2 -> 4
# 3 -> 9
# 4 -> 16
부터 를 원하지 않는 경우.dict
다른 사람들이 제안했듯이, 여기 구현 방법에 대한 질문에 대한 직접적인 대답이 있습니다.__iter__
사용자 지정 딕트의 조잡한 예:
class Attribute:
def __init__(self, key, value):
self.key = key
self.value = value
class Node(collections.Mapping):
def __init__(self):
self.type = ""
self.attrs = [] # List of Attributes
def __iter__(self):
for attr in self.attrs:
yield attr.key
여기에 잘 설명된 발전기를 사용합니다.
우리가 물려받은 것은Mapping
구합해야니다현을 구현해야 .__getitem__
그리고.__len__
:
def __getitem__(self, key):
for attr in self.attrs:
if key == attr.key:
return attr.value
raise KeyError
def __len__(self):
return len(self.attrs)
경우에 따라 작동할 수 있는 한 가지 옵션은 사용자 정의 클래스를 다음에서 상속하도록 만드는 것입니다.dict
만약 이것이 딕트처럼 행동한다면 이것은 논리적인 선택처럼 보입니다. 아마도 딕트여야 할 것입니다.이런 식으로, 당신은 딕트와 같은 반복을 무료로 얻을 수 있습니다.
class MyDict(dict):
def __init__(self, custom_attribute):
self.bar = custom_attribute
mydict = MyDict('Some name')
mydict['a'] = 1
mydict['b'] = 2
print mydict.bar
for k, v in mydict.items():
print k, '=>', v
출력:
Some name
a => 1
b => 2
dict에서, dict를 합니다.iter
를 들어, 키 예: 건뛰기키2
궁지에 몰렸을 때.
# method 1
class Dict(dict):
def __iter__(self):
keys = self.keys()
for i in keys:
if i == 2:
continue
yield i
# method 2
class Dict(dict):
def __iter__(self):
for i in super(Dict, self).__iter__():
if i == 2:
continue
yield i
언급URL : https://stackoverflow.com/questions/4019971/how-to-implement-iter-self-for-a-container-object-python
'it-source' 카테고리의 다른 글
Oracle SQL의 숫자 형식 (0) | 2023.07.20 |
---|---|
플라스크에서 자바스크립트로 데이터를 템플릿으로 전달하려면 어떻게 해야 합니까? (0) | 2023.07.20 |
Oracle에서 일주일 중 첫 번째와 마지막 날을 얻는 방법은 무엇입니까? (0) | 2023.07.20 |
Oracle SQL에서 MERGE를 수행할 때 소스에서 일치하지 않는 행을 업데이트하려면 어떻게 해야 합니까? (0) | 2023.07.20 |
python: 디렉터리를 두 단계 위로 가져옵니다. (0) | 2023.07.20 |