In [ ]:
import functools
In [ ]:
def deco(func):
@functools.wraps(func)
def wrapped():
pass
return wrapped
@deco
def foo():
print('Hey')
foo.__name__
In [ ]:
def validate_user_id(func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
if 'user_id' not in kwargs or kwargs['user_id'] == 0:
print('user_id is wrong')
return
print('user_id is correct')
return func(*args, **kwargs)
return wrapped
def log_access(func):
@functools.wraps(func)
def wrapped(*args, **kwargs):
print('{} was called'.format(func.__name__))
return func(*args, **kwargs)
return wrapped
@log_access
@validate_user_id
def feedback(user_id, message):
print('Feedback received')
# feedback = log_access(validate_user_id(feedback))
data = {
'message': 'Your app is awesome!',
'user_id': 42
}
feedback(**data)
In [ ]:
In [ ]:
class User:
def __init__(self, name, email):
self.name = name
self.email = email
def get_email_data(self):
return {
'name': self.name,
'email': self.email
}
jane = User('Jane Doe', 'janedoe@example.com')
print(jane.get_email_data())
In [ ]:
In [ ]:
class Singleton:
instance = None
def __new__(cls):
if cls.instance is None:
cls.instance = super().__new__(cls)
return cls.instance
a = Singleton()
b = Singleton()
a is b
In [ ]:
In [ ]:
class User:
def __init__(self, name, email):
self.name = name
self.email = email
def __str__(self):
return '{} <{}>'.format(self.name, self.email)
jane = User('Jane Doe', 'janedoe@example.com')
print(jane)
In [ ]:
In [ ]:
class User:
def __init__(self, name, email):
self.name = name
self.email = email
def __hash__(self):
return hash(self.email)
def __eq__(self, obj):
return self.email == obj.email
jane = User('Jane Doe', 'jdoe@example.com')
joe = User('Joe Doe', 'jdoe@example.com')
print(jane == joe)
In [ ]:
print(hash(jane))
print(hash(joe))
In [ ]:
user_email_map = {user: user.name for user in [jane, joe]}
print(user_email_map)
In [ ]:
In [ ]:
class Researcher:
def __getattr__(self, name):
return 'Nothing found :('
def __getattribute__(self, name):
return 'nope'
obj = Researcher()
print(obj.attr)
print(obj.method)
print(obj.DFG2H3J00KLL)
In [ ]:
In [ ]:
class Researcher:
def __getattr__(self, name):
return 'Nothing found :(\n'
def __getattribute__(self, name):
print('Looking for {}'.format(name))
return object.__getattribute__(self, name)
obj = Researcher()
print(obj.attr)
print(obj.method)
print(obj.DFG2H3J00KLL)
In [ ]:
In [ ]:
class Ignorant:
def __setattr__(self, name, value):
print('Not gonna set {}!'.format(name))
obj = Ignorant()
obj.math = True
In [ ]:
print(obj.math)
In [ ]:
In [ ]:
class Polite:
def __delattr__(self, name):
value = getattr(self, name)
print(f'Goodbye {name}, you were {value}!')
object.__delattr__(self, name)
obj = Polite()
obj.attr = 10
del obj.attr
In [ ]:
In [ ]:
class Logger:
def __init__(self, filename):
self.filename = filename
def __call__(self, func):
with open(self.filename, 'w') as f:
f.write('Oh Danny boy...')
return func
logger = Logger('log.txt')
@logger
def completely_useless_function():
pass
In [ ]:
completely_useless_function()
with open('log.txt') as f:
print(f.read())
In [ ]:
In [ ]:
import random
class NoisyInt:
def __init__(self, value):
self.value = value
def __add__(self, obj):
noise = random.uniform(-1, 1)
return self.value + obj.value + noise
a = NoisyInt(10)
b = NoisyInt(20)
In [ ]:
for _ in range(3):
print(a + b)
In [ ]:
In [ ]:
for number in range(5):
print(number & 1)
In [ ]:
for letter in 'python':
print(ord(letter))
In [ ]:
iterator = iter([1, 2, 3])
In [ ]:
print(next(iterator))
In [ ]:
In [ ]:
class SquareIterator:
def __init__(self, start, end):
self.current = start
self.end = end
def __iter__(self):
return self
def __next__(self):
if self.current >= self.end:
raise StopIteration
result = self.current ** 2
self.current += 1
return result
for num in SquareIterator(1, 4):
print(num)
In [ ]:
In [ ]:
class IndexIterable:
def __init__(self, obj):
self.obj = obj
def __getitem__(self, index):
return self.obj[index]
for letter in IndexIterable('str'):
print(letter)
# Какой еще объект может быть вместо строки?
In [ ]:
In [ ]:
import collections
print(isinstance(SquareIterator(1, 10), collections.Iterable))
print(isinstance(IndexIterable('123'), collections.Iterable))
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
import asyncio
class Ranger:
def __init__(self, limit):
self.limit = limit
def __aiter__(self):
return self
async def __anext__(self):
await asyncio.sleep(1)
if self.limit == 0:
raise StopAsyncIteration
self.limit -= 1
return self.limit + 1
async def main():
async for val in Ranger(10):
print(val)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
In [ ]:
In [ ]:
In [ ]:
async def arange(start, stop):
current = start
while current <= stop - 1:
yield current
current += 1
async def main():
async for num in arange(10, 20):
print(num)
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
In [ ]:
In [ ]:
async def main():
return [num async for num in arange(10, 20)]
loop = asyncio.get_event_loop()
loop.run_until_complete(main())
In [ ]:
In [ ]:
In [ ]:
with open('access_log.log', 'a') as f:
f.write('New Access\n')
In [ ]:
class open_file:
def __init__(self, filename, mode):
self.f = open(filename, mode)
def __enter__(self):
return self.f
def __exit__(self, *args):
self.f.close()
In [ ]:
with open_file('test.log', 'w') as f:
f.write('Inside `open_file` context manager')
In [ ]:
with open_file('test.log', 'r') as f:
print(f.readlines())
In [ ]:
In [ ]:
class suppress_exception:
def __init__(self, exc_type):
self.exc_type = exc_type
def __enter__(self):
return
def __exit__(self, exc_type, exc_value, traceback):
if exc_type == self.exc_type:
print('Nothing happend.')
return True
In [ ]:
with suppress_exception(ZeroDivisionError):
really_big_number = 1 / 0
In [ ]:
import contextlib
with contextlib.suppress(ValueError):
raise ValueError
In [ ]:
In [ ]:
import time
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
import aiohttp
import asyncio
async def fetch(client):
async with client.get('http://python.org') as resp:
assert resp.status == 200
return await resp.text()
async def main(loop):
async with aiohttp.ClientSession(loop=loop) as client:
html = await fetch(client)
print(html[:96])
loop = asyncio.get_event_loop()
loop.run_until_complete(main(loop))
In [ ]:
In [ ]:
In [ ]:
class Descriptor:
def __get__(self, obj, obj_type):
print('get')
def __set__(self, obj, value):
print('set')
def __delete__(self, obj):
print('delete')
class Class:
attr = Descriptor()
instance = Class()
In [ ]:
instance.attr
In [ ]:
instance.attr = 10
In [ ]:
del instance.attr
In [ ]:
In [ ]:
class Value:
def __init__(self):
self.value = None
@staticmethod
def _prepare_value(value):
return value * 10
def __get__(self, obj, obj_type):
return self.value
def __set__(self, obj, value):
self.value = self._prepare_value(value)
In [ ]:
class Class:
attr = Value()
instance = Class()
instance.attr = 10
print(instance.attr)
In [ ]:
In [ ]:
In [ ]:
# Что происходит в момент доступа к атрибуту — instance.attr (Чтение)
def pseudo_read():
if hasattr(instance.__class__, 'attr'):
obj = instance.__class__.attr
obj_type = obj.__class__
if hasattr(obj_type, '__get__') and (
hasattr(obj_type, '__set__') or 'attr' not in instance.__dict__
):
return obj_type.__get__(obj, instance, instance.__class__)
return instance.__dict__['attr']
# 1. Data Descriptors
# 2. instance.__dict__
# 3. Non-Data Descriptors
# 4. class.__dict__
# 5. base classes
# instance.attr => type(instance).__dict__['attr'].__get__(instance, type(instance))
# Class.attr => Class.__dict__['attr'].__get__(None, Class)
In [ ]:
In [ ]:
# Что происходит во время — instance.attr = 10 (Записи)
def pseudo_write():
if hasattr(instance.__class__, 'attr'):
obj = instance.__class__.attr
obj_type = obj.__class__
if hasattr(obj_type, '__set__'):
obj_type.__set__(obj, instance, 10)
return
instance.__dict__['attr'] = 10
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
class Class:
def method(self):
pass
obj = Class()
print(obj.method)
print(Class.method)
In [ ]:
In [ ]:
In [ ]:
def summator(x, y):
return x + y
lolwhat = summator.__get__(10)
lolwhat(21)
In [ ]:
In [ ]:
class User:
def __init__(self, first_name, last_name):
self.first_name = first_name
self.last_name = last_name
@property
def full_name(self):
return f'{self.first_name} {self.last_name}'
amy = User('Amy', 'Jones')
print(amy.full_name)
print(User.full_name)
In [ ]:
class Property:
def __init__(self, getter):
self.getter = getter
def __get__(self, obj, obj_type=None):
if obj is None:
return self
return self.getter(obj)
In [ ]:
class Class:
@property
def original(self):
return 'original'
@Property
def custom_sugar(self):
return 'custom sugar'
def custom_pure(self):
return 'custom pure'
custom_pure = Property(custom_pure)
In [ ]:
obj = Class()
print(obj.original)
print(obj.custom_sugar)
print(obj.custom_pure)
In [ ]:
In [ ]:
class StaticMethod:
def __init__(self, func):
self.func = func
def __get__(self, obj, obj_type=None):
return self.func
In [ ]:
class ClassMethod:
def __init__(self, func):
self.func = func
def __get__(self, obj, obj_type=None):
if obj_type is None:
obj_type = type(obj)
def new_func(*args, **kwargs):
return self.func(obj_type, *args, **kwargs)
return new_func
In [ ]:
class Class:
__slots__ = ['anakin']
def __init__(self):
self.anakin = 'the chosen one'
obj = Class()
obj.luke = 'the chosen too'
In [ ]:
In [ ]:
class Class:
...
In [ ]:
obj = Class()
In [ ]:
type(obj)
In [ ]:
type(Class)
In [ ]:
type(type)
In [ ]:
issubclass(Class, type)
In [ ]:
issubclass(Class, object)
In [ ]:
In [ ]:
def dummy_factory():
class Class:
pass
return Class
Dummy = dummy_factory()
obj = Dummy()
In [ ]:
NewClass = type('NewClass', (), {})
print(NewClass)
print(NewClass())
In [ ]:
In [ ]:
class Meta(type):
def __new__(cls, name, parents, attrs):
print('Creating {}'.format(name))
if 'class_id' not in attrs:
attrs['class_id'] = name.lower()
return super().__new__(cls, name, parents, attrs)
In [ ]:
class A(metaclass=Meta):
pass
In [ ]:
print('A.class_id: "{}"'.format(A.class_id))
In [ ]:
class Meta(type):
def __init__(cls, name, bases, attrs):
print('Initializing — {}'.format(name))
if not hasattr(cls, 'registry'):
cls.registry = {}
else:
cls.registry[name.lower()] = cls
super().__init__(name, bases, attrs)
class Base(metaclass=Meta): pass
class A(Base): pass
class B(Base): pass
In [ ]:
print(Base.registry)
print(Base.__subclasses__())