a follow-up question on this question: i ran the code below on python 3.5 and python 3.6 - with very different results:
class Container:
KEYS = ('a', 'b', 'c')
def __init__(self, a=None, b=None, c=None):
self.a = a
self.b = b
self.c = c
def keys(self):
return Container.KEYS
def __getitem__(self, key):
if key not in Container.KEYS:
raise KeyError(key)
return getattr(self, key)
def __str__(self):
# python 3.6
# return f'{self.__class__.__name__}(a={self.a}, b={self.b}, c={self.c})'
# python 3.5
return ('{self.__class__.__name__}(a={self.a}, b={self.b}, '
'c={self.c})').format(self=self)
data0 = Container(a=1, b=2, c=3)
print(data0)
data3 = Container(**data0, b=7)
print(data3)
as stated in the previous question this raises
TypeError: type object got multiple values for keyword argument 'b'
on python 3.6. but on python 3.5 i get the exception:
KeyError: 0
moreover if i do not raise KeyError
but just print out the key
and return
in __getitem__
:
def __getitem__(self, key):
if key not in Container.KEYS:
# raise KeyError(key)
print(key)
return
return getattr(self, key)
this will print out the int
sequence 0, 1, 2, 3, 4, ...
. (python 3.5)
so my questions are:
what has changed between the releases that makes this behave so differently?
where are these integers coming from?
UPDATE : as mentioned in the comment by λuser: implementing __iter__
will change the behavior on python 3.5 to match what python 3.6 does:
def __iter__(self):
return iter(Container.KEYS)