When a class naturally matches, or needs to emulate, a built-in type's interface
Don't expect speed adavtange
In fact, it might be slower. (Might due to the overhead of a function call)
import timeit
min(timeit.repeat("L = list(range(100)); x = L.__len__()", number=10000, repeat=3))
0.042683540488979155
min(timeit.repeat("L = list(range(100)); x = len(L)", number=10000, repeat=3))
0.03931401884886343
__init__
__repr, __str__
__call__
__getattr__
__setattr__
__getitem__
__setitem__
__len__
__bool__
__lt__, __gt__, __le__, __ge__, __eq__, __ne__
__iter__, __next__
__contains__
__index__
class Indexer(object):
data = [5, 6, 7, 8, 9]
def __getitem__(self, index):
print("getitem: ", index)
return self.data[index]
x = Indexer()
x[2]
getitem: 2
7
x[2:4]
getitem: slice(2, 4, None)
[7, 8]
Handle the slice object (slice objects have attribute start, stop and step)
class Indexer(object):
data = [5, 6, 7, 8, 9]
def __getitem__(self, index):
if isinstance(index, int):
print("indexing", index)
else:
print("slicing", index.start, index.stop, index.step)
return self.data[index]
x = Indexer()
x[2:4]
slicing 2 4 None
[7, 8]
__getitem__
¶In absence of more-specific methods, __getitem__
may be used in the following cases.
class StepIndexer(object):
def __getitem__(self, i):
return self.data[i]
x = StepIndexer()
x.data = "1234"
# iteration
for i in x:
print(i)
1 2 3 4
# in
"1" in x
True
# list comprehensions
[i for i in x]
['1', '2', '3', '4']
# map
list(map(lambda x: int(x) * 2, x))
[2, 4, 6, 8]
# tuple assignment
(a, b, c, d) = x
a, b, d
('1', '2', '4')
# type constructor
list(x)
['1', '2', '3', '4']
__setitem__
¶For instance-indexing assignment. (e.g. X[i] = 5)
class IndexSeter(object):
data = [1, 2, 3, 4]
def __setitem__(self, index, value):
self.data[index] = value
x = IndexSeter()
x[2] = 5
x.data
[1, 2, 5, 4]
In Python 2 only, there are also __getslice__
and __setslice__
They're removed in Python3.
Thus, even in Python2, __getitem__
and __setitem__
should be used
__index__
is not indexing !!!¶Returning an iteger value for an instance and is used by built-ins that convert to digit strings
class C(object):
def __index__(self):
return 255
x = C()
hex(x)
'0xff'
__iter__
, __next__
¶__iter__
first than __getitem__
__iter__
is prefered. It supports general iteration context better than __getitem__
__iter__
is invoked, it's expected to return an iterator object.__next__
until a StopIteration exception__getitem__
should still be used.class Squares(object):
def __init__(self, start, stop):
self.value = start - 1
self.stop = stop
def __iter__(self):
return self
def __next__(self):
if self.value == self.stop:
raise StopIteration
self.value += 1
return self.value**2
def test_iter():
x = Squares(1, 5)
I1 = iter(x)
I2 = iter(x)
print("I1: ", next(I1))
print("I1: ", next(I1))
print("I1: ", next(I1))
print("I2: ", next(I2))
test_iter()
I1: 1 I1: 4 I1: 9 I2: 16
class Squares(object):
def __init__(self, start, stop):
self.start = start
self.stop = stop
def __iter__(self):
for value in range(self.start, self.stop + 1):
yield value**2
# Defined above
test_iter()
I1: 1 I1: 4 I1: 9 I2: 1
class Squares(object):
def __init__(self, start, stop):
self.start = start
self.stop = stop
def __iter__(self):
return SquaresIter(self.start, self.stop)
class SquaresIter(object):
def __init__(self, start, stop):
self.value = start - 1
self.stop = stop
def __next__(self):
if self.value == self.stop:
raise StopIteration
self.value += 1
return self.value**2
# Defined above
test_iter()
I1: 1 I1: 4 I1: 9 I2: 1
__contains__
, __iter__
, __getitem__
¶__contains__
is called when in mebership operator is used__iter__
or __geitem__
is enough__contains__
should define membership as applying to keys for a mapping and as a search for sequencesclass C(object):
data = [1, 2, 3, 4]
def __contains__(self, x):
return x in self.data
x = C()
1 in x
True
__getattr__
and __setattr__
¶They are used when object.attribute
presents
__getattr__
¶It's called whenever you try to qualify an instance with an undefined attribute name. (e.g. object.attribute)
It's not called if Python can find the attibute from its inheritance tree
Usage
class Empty(object):
def __getattr__(self, attrname):
if attrname == "age":
return 40
else:
raise AttributeError(attrname)
x = Empty()
x.age
40
__getattr__
__getattr__
(or __getatttribute__
) and a default display is used instead)__setattr__
¶seflf.attr = value
becomes self.__setattr__('attr', value)
Assigning to any self attriibtues calls __setattr__
. Even if it's in __setattr__
To avoid loops, use attribute dict, self.__dict__['name'] = x
or by routing any attribute assignments to a higher superclass
class Accesscontrol(object):
def __setattr__(self, attr, value):
if attr == "age":
self.__dict__[attr] = value + 10
else:
raise AttributeError(attr + " not allowed")
x = Accesscontrol()
x.age = 50
x.age
60
x.name = "Bob"
--------------------------------------------------------------------------- AttributeError Traceback (most recent call last) <ipython-input-23-6dddaa83334c> in <module>() ----> 1 x.name = 'Bob' <ipython-input-22-08a9966a8fa9> in __setattr__(self, attr, value) 4 self.__dict__[attr] = value + 10 5 else: ----> 6 raise AttributeError(attr + ' not allowed') 7 8 x = Accesscontrol() AttributeError: name not allowed
__delattr__
: Used when del object.attr present. (Must avoid recursive loops as __setattr__
)__getattribute__
: Intercepts *all* attribute fetches, not just those that are undefined. This would need to avoid loop__get__
and __set__
methods of a class with accesses to a specific class attribute__repr__
, __str__
¶__repr__
vs __str__
¶__str__
__repr__
__repr__
is used everywhere, except by print and str when __str__
is defined.__repr__
if no __str__
is defined, but the inverse is not__str__
might only apply whne objects appear at the top level of a print operationclass Printer(object):
def __init__(self, val):
self.val = val
def __str__(self):
return str(self.val)
objs = [Printer(2), Printer(3)]
for x in objs:
print(x)
print(objs)
2 3 [<__main__.Printer object at 0x02C9B970>, <__main__.Printer object at 0x02C9B870>]
class Printer(object):
def __init__(self, val):
self.val = val
def __repr__(self):
return str(self.val)
objs = [Printer(2), Printer(3)]
for x in objs:
print(x)
print(objs)
2 3 [2, 3]
__repr__
¶Displaying the value of a method riggers the __repr__
of the method's class, in order ot display the class
class LoopRepr(object):
def __init__(self):
self.data = "loop"
def __repr__(self):
print(self)
return self.data
r = LoopRepr()
print(r)
--------------------------------------------------------------------------- RuntimeError Traceback (most recent call last) <ipython-input-3-84e11e0ed7d4> in <module>() 8 9 r = LoopRepr() ---> 10 print(r) <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 <ipython-input-3-84e11e0ed7d4> in __repr__(self) 4 5 def __repr__(self): ----> 6 print(self) 7 return self.data 8 RuntimeError: maximum recursion depth exceeded while getting the str of an object
class Adder(object):
def __init__(self, value=0):
self.val = value
def __add__(self, other):
return self.val + other
x = Adder(5)
x + 2
7
2 + x
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-28-c1dc2303a7c3> in <module>() ----> 1 2 + x TypeError: unsupported operand type(s) for +: 'int' and 'Adder'
Python calls __radd__
only when the object on the right side of the + is your classs instance, but the object on the left is not and __add__
handles all the other cases.
When instance of different classes appear mixed in an expression, Python prefers the class of the one on the left
The order is reversed in __radd__
: self is really on the right of the +, and the other is on the left.
class Adder(object):
def __init__(self, value=0):
self.val = value
def __add__(self, other):
return self.val + other
def __radd__(self, other):
print("radd ", self.val, other)
return other + self.val
x = Adder(5)
2 + x
radd 5 2
7
__add__
in__radd__
¶For truly commutative operations
class Adder(object):
def __init__(self, val):
self.val = val
def __add__(self, other):
return self.val + other
__radd__ = __add__
x = Adder(5)
print(x + 2)
print(2 + x)
7 7
To implement +=, code __iadd__
or __add__
. The latter is used if the former is absent
It allows for more efficient in-place changes to be coded.
class Number(object):
def __init__(self, val):
self.val = val
def __iadd__(self, other):
self.val += other
return self
x = Number(5)
x += 1
x.val
6
__call__
¶If defined, Python runs a __call__
for function call expressions applied to your instances, passing along whatever positional or keyword arguments were sent
All the argument-passing modes are supported by the __call__
Useful when interfacing with APIs(i.e. libraries)
Allows us to code objects that conform to an expected function call interface, but also retain state information
class Callee(object):
def __call__(self, *pargs, **kargs):
print("Called: ", pargs, kargs)
c = Callee()
c(1, 2, 3)
Called: (1, 2, 3) {}
__lt__
, __gt__
)¶__eq__
and __ne__
should be defined to ensure that both operatos behave correctlyclass Comparator(object):
def __init__(self, val):
self.val = val
def __lt__(self, other):
return self.val < other
x = Comparator(5)
x < 50
True
x > 50
--------------------------------------------------------------------------- TypeError Traceback (most recent call last) <ipython-input-34-cfde3aaa852a> in <module>() ----> 1 x > 50 TypeError: unorderable types: Comparator() > int()
__bool__
, __len__
¶__bool__
first then __len__
(zero or not)__nonzero__
to __bool__
class Truth(object):
def __bool__(self):
return True
def __len__(self):
return 1
x = Truth()
if x:
print("True")
True
__del__
¶It's destructor but not recommanded to use. Due to the following reason
It's often better to code termination activities in an explicityly called method(e.g. shutdown)
The following methods would be mentioned in future chapters
__enter__
, __exit__
: used in with statement__get__
, __set__
: used in descriptor__new__
: used in metaclasses