class Meta(type):
@property
def value(cls):
return cls._value
@value.setter
def value(cls, val):
cls._value = val + 1
class A(metaclass=Meta):
_value = 1
@property
def value(self):
return self._value + 2
a = A()
print(A.value, end='')
A.value = 5
print(a.value, end='')
print(A.value)
from typing import Any
class MetaAnno(type):
def __new__(cls, name, bases, attrs):
annotations = attrs.get('__annotations__', {})
for key, value in annotations.items():
if key in attrs:
attrs[key] = value(attrs[key])
return super().__new__(cls, name, bases, attrs)
class A(metaclass=MetaAnno):
x: str
y: lambda x: x * 2
z: lambda x: x + 1
x = 10
y = 3
z = 5
print(A.x, end='')
print(A.y, end='')
print(A.z)
class MetaSlot(type):
def __new__(cls, name, bases, dct):
slots = dct.get('__slots__', [])
for base in bases:
slots.extend(getattr(base, '__slots__', []))
dct['__slots__'] = tuple(set(slots))
return super().__new__(cls, name, bases, dct)
class A(metaclass=MetaSlot):
__slots__ = ['x']
class B(A):
__slots__ = ['y']
obj = B()
obj.x = 1
obj.y = 2
try:
obj.z = 3
except AttributeError:
print('error', end='')
print(len(obj.__slots__))
class Meta(type):
@property
def x(cls):
return cls._x + 1
@x.setter
def x(cls, val):
cls._x = val - 1
class A(metaclass=Meta):
_x = 1
@property
def x(self):
return self._x + 2
@x.setter
def x(self, val):
self._x = val - 2
a = A()
print(A.x, end='')
print(a.x, end='')
A.x = 5
print(a.x, end='')
a.x = 9
print(a.x)
class Desc:
def __get__(self, obj, type=None):
if obj is None:
return self
return getattr(obj, '_x', 1)
def __set__(self, obj, val):
obj._x = val + 1
class Base:
__slots__ = ('_x',)
x = Desc()
class Child(Base):
__slots__ = ()
def __init__(self):
self.x = 2
b = Base()
c = Child()
print(b.x, end='')
b.x = 3
print(b.x, end='')
print(c.x)
from contextlib import contextmanager
@contextmanager
def ctx(x):
print(x, end='')
try:
yield x + 1
finally:
print(x + 2, end='')
def deco(f):
def wrapper(*args):
print('s', end='')
res = f(*args)
print('e', end='')
return res
return wrapper
@deco
def test():
with ctx(1) as a, ctx(2) as b:
print(a + b, end='')
return 0
test()
class A:
def __init__(self):
print(1, end='')
super().__init__()
class B:
def __init__(self):
print(2, end='')
super().__init__()
class C:
def __init__(self):
print(3, end='')
class D(A, B, C):
def __init__(self):
print(4, end='')
super().__init__()
print("start", end='')
D()
print("end")
def make_gens():
funcs = []
for x in range(3):
def gen(n=[x]):
n[0] += 2
yield n[0]
funcs.append(gen)
return funcs
g1, g2, g3 = make_gens()
print(next(g1()), end='')
print(next(g2()), end='')
print(next(g1()), end='')
print(next(g3()))
class Prop:
def __init__(self, value):
self.value = value
def __get__(self, obj, owner=None):
if obj is None:
return self
obj.__dict__['x'] = self.value + 1
return self.value
def __set__(self, obj, value):
self.value = value - 1
class C:
x = Prop(2)
c = C()
print(c.x, end='')
print(c.__dict__['x'], end='')
c.x = 6
print(c.x)