__bool__()
class Rectangle:
def __init__(self, w, h):
self. width = w
self. height = h
def __bool__(self):
if self.width and self.height:
return True
else:
return False
>>> bool(Rectangle(10, 15))
True
>>> bool(Rectangle(0, 1))
False
Also, if an object supplies a __len__() method, python will consider False objects of zero length.
and, or and not will now use this method
mathematical operators
Bitwise operations
Not terribly important to me
operation variations
There is an operator, each has a left hand method, right hand method, and inline method.
right hand is the left hand prepended with ‘r’
__add__() becomes __radd__()
inline adds an “i”
__add__() becomes __iadd__()
division and modulo don’t have an inline method.
Bitwise inversion doesn’t have a right hand or inline method.
Numbers
import decimal
round(decimal.Decimal(‘3.14’), 1) == Decimal(‘3.1’)
round(decimal.Decimal(‘3.14’)) == 3
round(256, -1) == 260
round(512, -2) == 500
Sign Operations
Comparison operators
Iterables
an object is iterable if passing it to the built-in iter() returns an iterator. iter() first inspects the object, looking for an __iter__() method
two things required
if Python sees something that stops a loop while the iterator still has values in it, the iterator remains with those values in it. This happens in break, return, or raise
raise StopIteration is what finally stops it
Repeatable Generators
now
def repeatable(generator):
"""a decorator to turn a generator into an object that can be iterated multiple times"""
class RepeatableGenerator:
def \_\_init\_\_(self, \*args, \*\*kwargs):
self.args = args
self.kwargs = kwargs
def \_\_iter\_\_(self):
return iter(generator(\*self.args, \*\*self.kwargs))
return RepeatableGenerator@repeatable
def gen(max):
__for x in range(max):
____yield x
etc.
Problems with this example:
@functools.wraps(generator)
def wrapper(*args, **kwargs):
__return RepeatableGenerator(*args, __**kwargs)
**return wrapper **
instead of RepeatableGenerator
__getitem__()
__setitem__()
__getitem__():
__setitem__():
append and insert add items.
__setitem__ does not.
__contains__()
__delitem__()
remove()
del keyword is just like remove. Items after the deleted one are moved left. It calls the __delitem__() method rather than the explicit remove() method call.
in is the keyword that calls __contains__(). Contains accepts an object and returns True or False
Mappings
keys to mappings may be any hashable object:
slice objects are not hashable, so they can’t be keys
mapping methods
__call__()
makes an object callable. Anything can be callable
as a function, it can be decorated any number of times, but any decorator needs to account for the instance being passed as the first argument.
context managers
context managers are used in a with statement
Allows an object to define what it means to work within the context of that object - ex. setup and clean up.
two distinct steps:
**__enter__() : **
receives no additional arguments, just the instance. provides initialization of code block in with statement
if with statement includes an as clause, __enter__() returns a value to that variable
__exit__():
it’s job is to return the context to whatever it was prior to the with statement. In the case of files, it closes it. this is still called even if return, yield, continue, or break statements end the block
exit gets three arguments to determine if the block stopped normally or there was an exception. class of the exception, the instance of that class, and traceback object. Any implementation of exit must accept these three arguments.