Proba

You might also like

Download as txt, pdf, or txt
Download as txt, pdf, or txt
You are on page 1of 23

@classmethod

def verify_coord(cls,n):
if n != '__x' and n != '__y':
raise AttributeError("���������� : 'x', 'y'")

==============================================================================
print('\n')
print('------------------------------------------- Point')
print('\n')

class Point:
__slots__ = ['__a', '__b', '__c', '__d', '__dict__']

def __init__(self, a=(0,0), c=(0,0)):


self.__a = a
self.__c = c
self.__b,self.__d = self.change(a,c)

def __del__(self):
print( "�������� ��������� "+ str(self))

def __getattribute__(self, item):


#print(f"__getattribute__ item = {item} ")
return object.__getattribute__(self, item)

def __setattr__(self, key, value):


#print("__setattr__")
#print(f"key = {key} value = {value}")
if key != '_Point__a' and key != '_Point__c' and \
key != '_Point__b' and key != '_Point__d' and key != '__dict__':
#print(f"key {key} != '__a', '__b', '__c', '__d' ")
raise AttributeError("���������� : '__a', '__b', '__c', '__d' ")
self.__dict__[key] = value
object.__setattr__(self, key, value)
# ����� ����������� ������ �� �������:
# ��� �� ������ �� ������� __dict__
# ��������� self.__dict__[key] = value
#

@staticmethod
def change(*args):
#print(f"len(args) = {len(args)}")
a,b = args
x1,y1 = a
x2,y2 = b
a = x1,y2
b = x2,y1
return a,b

def get_point(self):
print( self.__a, self.__b, self.__c, self.__d)
def set_point(self, a, c):
self.__a = a
self.__c = c
self.__b,self.__d = self.change(a,c)

pt = Point((1,4),(6,1))

print(pt.__dict__)
#print(__a) # NameError: name '__a' is not defined
#print(a) # NameError: name '__a' is not defined
#print(pt.a) # AttributeError: 'Point' object has no attribute 'a'
#print(pt.__a) # AttributeError: 'Point' object has no attribute '__a'
pt.get_point()
pt.set_point((1,5),(6,2))
pt.get_point()
print(pt.__dict__)
#pt.e = 7,8 # AttributeError: ���������� : '__a', '__b', '__c', '__d'
#print(pt.__dir__())

pt = 0 # �������� ��������� <__main__.Point object at 0x02C8CC30>

#res = Point.change((2,5),(7,2))
#print(f"res = {res}")

==============================================================================

print('\n')
print('------------------------------------------- Point2D')
print('\n')
class Point2D:

def __init__(self, x=0, y=0):


self.x = x
self.y = y

def __del__(self):
print( "�������� ��������� "+ str(self))

def __getattribute__(self, item):


#print(f"__getattribute__ item {item}")
return object.__getattribute__(self, item)

def __setattr__(self, key, value):


#print("__setattr__")
#print(f"key {key} value {value}")
if key != 'x' and key != 'y':
#print(f"key {key} != 'x' or 'y' ")
raise AttributeError("���������� : 'x' or 'y' ")
object.__setattr__(self, key, value)

def get_point(self):
print( self.x, self.y)
p = Point2D()
print(p.__dict__) # {'x': 0, 'y': 0}
p.x = 1
p.y = 4
print(p.__dict__) # {'x': 1, 'y': 4}
p.get_point() # 1 4
#p.z = 7 # AttributeError: ���������� : 'x' or 'y'
p = 0 # �������� ��������� <__main__.Point2D object at 0x02C86238>

def switch_element(self,argument, tup):


print("switch_element switch_element switch_element")
if tup:
print(f"tup is {tup}")
switcher = {
'a': self.a,
'b': self.b,
'c': self.c,
'd': self.d
}
return (switcher.get(argument, False))

def switch_name(self,argument):
print("switch_name switch_name switch_name")
switcher = {
'a': True,
'b': True,
'c': True,
'd': True,
}
return (switcher.get(argument, False))

name = switch_name(arg)
print(f"name = {name}")

element = switch_element(arg,self.CORRECT)
print(f"element = {element}")

==============================================================================

==============================================================================
������ 1
�������� property. ��������� @property

class Point:

def __init__(self, x=0, y=0):


self.__x = x
self.__y = y

# ��������������� ��������� �����


# ����������� ������ ������ ������
# �� ����� ��������� � ��������� ����������
# ���������� ������
# ������ �������� ��� self
# �� ������������: ��_������.�������� ������
# Point.__check_value(x)
def __check_value(arg):
if isinstance(arg,int):
return True
return False

def get_coord(self):
print("����� __get_coord")
return self.__x, self.__y

def set_coord(self, x, y):


print(f"����� __set_coord x = {x} y = {y} ")
Point.__check_value(x) and Point.__check_value(y)
self.__x = x
self.__y = y

def del_coord(self):
del self.__x
del self.__y

pt = Point() # ������ �������� ������


print(pt.__dict__) # {'_Point__x': 0, '_Point__y': 0}
pt.set_coord(1,2) # ������������� �������
print(pt.get_coord()) # (1, 2)
print(pt.__dict__) # {'_Point__x': 1, '_Point__y': 2}
pt.set_coord(5,8) # ������������� �������
print(pt.__dict__) # {'_Point__x': 5, '_Point__y': 8}
pt.del_coord() # ������ ��� ����������
print(pt.__dict__) # {}

������������� �����:
������� �� �������� � ��������
�������-�������� property

class Point:

def __init__(self, x=0, y=0):


self.__x = x
self.__y = y

# ��������������� ��������� �����


# ����������� ������ ������ ������
# �� ����� ��������� � ��������� ����������
# ���������� ������
# ������ �������� ��� self
# �� ������������: ��_������.�������� ������
# Point.__check_value(x)
def __check_value(arg):
if isinstance(arg,int):
return True
return False

def __get_coord(self):
print("����� __get_coord")
return self.__x, self.__y

# � ������� �� ������-�������� property


# ��������� ���������� ����� ��������
# ������ ���������� (tuple,list)
# arg - � ������ ������ ������
def __set_coord(self, arg ):
print(f"����� __set_coord arg = {arg}")
x,y = arg
Point.__check_value(x) and Point.__check_value(y)
self.__x = x
self.__y = y

def __del_coord(self):
del self.__x
del self.__y

coord = property(__get_coord, __set_coord, __del_coord)

pt = Point() # ������ �������� ������


print(pt.__dict__) # {'_Point__x': 0, '_Point__y': 0}

pt.coord = 1,2 # ������������� �������


print(pt.coord) # (1, 2)
print(pt.__dict__) # {'_Point__x': 1, '_Point__y': 2}

pt.coord = 13,25 # ������������� �������


print(pt.coord) # (13, 25)
print(pt.__dict__) # {'_Point__x': 13, '_Point__y': 25}

del pt.coord # ������ ��� ����������


print(pt.__dict__)# {}

������������� �����:
���������� ��������� @property

class Point:

def __init__(self, x=0, y=0):


self.__x = x
self.__y = y

# ��������������� ��������� �����


# ����������� ������ ������ ������
# �� ����� ��������� � ��������� ����������
# ���������� ������
# ������ �������� ��� self
# �� ������������: ��_������.�������� ������
# Point.__check_value(x)
def __check_value(arg):
if isinstance(arg,int):
return True
return False

@property
def coord(self):
print("����� __get_coord")
return self.__x, self.__y

# � ������� �� ������-�������� property


# ��������� ���������� ����� ��������
# ������ ���������� (tuple,list)
# arg - � ������ ������ ������
@coord.setter
def coord(self, arg ):
print(f"����� __set_coord arg = {arg}")
x,y = arg
Point.__check_value(x) and Point.__check_value(y)
self.__x = x
self.__y = y

@coord.deleter
def coord(self):
del self.__x
del self.__y

pt = Point() # ������ �������� ������


print(pt.__dict__) # {'_Point__x': 0, '_Point__y': 0}

pt.coord = 1,2 # ������������� �������


print(pt.coord) # (1, 2)
print(pt.__dict__) # {'_Point__x': 1, '_Point__y': 2}

pt.coord = 13,25 # ������������� �������


print(pt.coord) # (13, 25)
print(pt.__dict__) # {'_Point__x': 13, '_Point__y': 25}

del pt.coord # ������ ��� ����������


print(pt.__dict__)# {}

==============================================================================
������ 2
�������� property. ��������� @property

������:
���������� ������� ������������ ������ �����������

���
������� (����� ����� �� 14 �� 20)
���� � ����� �������� � �������: ���� ������ (������ �����, ������, ����� �����),
��� � - ����� �� 0 �� 9
���, � �� (������������ ����� �� 20 � ����)

���� ������� ���� ������ �� ������ �����:


��� = ����� ������ �� ��� �����, ���������� �������� '������ �� ��������'
������� = ����� ����� ����� � ������ ���������
������� = ����� ������ � ������ �������
��� = ����� ������������ ����� � ������ ���������

from string import ascii_letters

class Person:
S_RUS = '�������������������������������-'
S_RUS_UPPER = S_RUS.upper()

def __init__(self, fio, old, ps, weight):


self.verify_fio(fio)

self.__fio = fio.split()
self.old = old
self.passport = ps
self.weight = weight

# �� �������� ������� ����������� �������


# �������� ������� ������
@classmethod
def verify_fio(cls, fio):
# �������: ��� ������?
# ���� ��� �� ������ = ���������
if type(fio) != str:
raise TypeError("��� ������ ���� �������")
# ���� ��� ������
# ������� �� �� ������ �� ��� ��������� ����������� ��������
f = fio.split()
if len(f) != 3:
raise TypeError("�������� ������ ������ ���")
# ��������: fio
# ������������ ������ ���������� �������
# �� ����� �������� ��������� letters
# ������ �������� ��� ���������� �������
# ascii_leters - �������� ���������� (����� � �������) �� ��������
# ��� �������� ����� ���� �� ������� string
# �� ���� ����������� � from string import ascii_leters
# ���� ��������
# cls.S_RUS - ����� ������� ����� � ���� ������� ������
# cls.S_RUS_UPPER - ������� ������� ����� � ���� ������� ������
letters = ascii_letters + cls.S_RUS + cls.S_RUS_UPPER
# � ����� ����� for �������� ������ f
# if len(s) < 1:
# � ������ ����� � �������� ������ ���� ��� �� ���� �����
# if len(s.strip(letters))
# ����� String.strip( ) - ������ ������� � ������� ����� ������� � �����
������
# � ������ ������ ��� ������� �������� letters - �������� ����������
��������
# ���� ������, ��, �������� �������� ������ ���������� �������
# ����� �� ��� ������ � ����� ������ ������ ����� �������
# ���� ��� �� ���, �� ���������� ���������
for s in f:
if len(s) < 1:
raise TypeError("� ��� ������ ���� ��� �� ���� ������")
if len(s.strip(letters)) != 0:
raise TypeError("� ��� ����� ������������ ������ ��������� �������
� �����")
# ������ � __init__ �������� ��� �������� ����� self
# self.verify_fio(fio)
# ���� ����� ���������� ��� ��������� - ��� ������ �� ����
# ��������� = ����� ������ �����

# ��������: old
# �������� ��� ��� ����� ����� int
# �������� ���������� ��������
@classmethod
def verify_old(self,old):
# ��������: old
# �������� ��� ��� ����� ����� int
# �������� ���������� ��������
# if type(old) != int or 14 > old or old > 120:
if type(old) != int or not 14 < old < 120:
raise TypeError("������� ������ ���� ����� ������ � ���������
[14:120]")

# ��������: weight
# ���������� ��������
@classmethod
def verify_weight(self,w):
if type(w) != float or not 20 < w < 120:
raise TypeError("��� ������ ���� ������������ ������ � ���������
[20:120]")

# ��������: ps
# �������� ���������� ������
# �������� ��� ��� ������
# if type(ps) != str:
# ���� ��� = ���������� ������
# ���� ��� ������
# ������� �� �� ������ �� ���� ��������� ����������� ��������
# s = ps.split()
# ���� ������ �� ����� 2
# � ������ ������� ������ �� ����� 4
# � ������ ������� ������ �� ����� 6
# ���������� ������
# �������� � ������ ����� for ��� �� ��� �����
# if not p.isdigit():
# ���� ����� isdigit() ����� ���������� False
# �� ������ � ������ ���� �� �������� �������
# ���������� ������
#
#
#
@classmethod
def verify_ps(self,ps):
if type(ps) != str:
raise TypeError("������� ������ ���� �������")
s = ps.split()
if len(s) != 2 or len(s[0])!= 4 or len(s[1])!= 6:
raise TypeError("�������� ������ ������ ��������")
for p in s:
if not p.isdigit():
raise TypeError("���� � ����� �������� ������ ���� �������")

# ���� � ���� ���� �������� �� �������� ���������


# ������ � ��������� ��������� ��������� ������
# ������ ����������, � ����� ����� �������, ������ � ������������
#
# �������� ��� - ��� ������� ���������� �� ������������� � ����� �������
# �� ����� ������������ ���������-����������
# ������ ������-�������� �� �������� ������ ����� � ��������
# ������, ������� ���������� ������, ���������� ���
# ������ ���������� �� �����
@property
def fio(self):
return self.__fio
#
# ������ ������-�������� �� ��������
# �������� ������ � ������
@property
def old(self):
return self.__old
@old.setter
def old(self,old):
self.verify_old(old)
self.__old = old
#
# ������ ������-�������� �� ����
# �������� ������ � ������
@property
def weight(self):
return self.__weight
@weight.setter
def weight(self,weight):
self.verify_weight(weight)
self.__weight = weight
#
# �������� ������-�������� �� ������ ��������
# �������� ������ � ������
@property
def passport(self):
return self.__passport
@passport.setter
def passport(self,ps):
self.verify_ps(ps)
self.__passport = ps

p = Person('��������� ��������� ���������', 52, '1234 567890', 85.5)


print(p.__dict__)
p.old = 53
p.weight = 75.3
p.passport = "4321 098765"
print(p.__dict__)

#
# ����� ���� ����� �������������� __init__
#
# def __init__(self, fio, old, ps, weight):
# self.verify_fio(fio)
# self.verify_old(old)
# self.verify_weight(weight)
# self.verify_ps(ps)
#
# self.__fio = fio.split()
# self.__old = old
# self.__passport = ps
# self.__weight = weight
#
# ������ ���� ��������
# ����� ���� �������������� ���������-����������
# � ������� � ����������� ��������
# �� ���������� ������ � ������� ��������� �������� ��������
# self.__old = old
# � ����� ��������� ����� self ������-�������� � ��������� ��������
# self.old = old
# ����� fio ��� ��� �� �������� ������
# � ����������
# def __init__(self, fio, old, ps, weight):
# self.verify_fio(fio)
#
# self.__fio = fio.split()
# self.old = old
# self.passport = ps
# self.weight = weight
#
#
==============================================================================

==============================================================================
������ 3
�������� property. ��������� @property

class BankAccount:

def __init__(self, name, balance, passport):


self.__name = name
self.__balance = balance
self.__passport = passport

def get_balance(self):
print('get_balance')
return self.__balance

def set_balance(self,value):
print('set_balance')
if not isinstance(value,(int,float)):
raise ValueError('�������� ������� ������ ���� �����')
self.__balance = value

def delete_balance(self):
print('delete_balance')
del self.__balance

balance = property(get_balance, set_balance,delete_balance)

ac = BankAccount('Alex', 1000000, 4567731654 )


print(ac.get_balance())
print(ac.balance)

# ������� �� �������� � ��������


# �������-�������� property
#
# ��� ���� ������ ��������� = ��������� ��� ��
#
# balance = property(fget=get_balance,
# fset=set_balance,
# fdel=delete_balance)
#
# balance = property(get_balance, set_balance,delete_balance)
#
#
# balance = property()
# balance = balance.getter(get_balance)
# balance = balance.setter(set_balance)
# balance = balance.deleter(delete_balance)
#

������������� �����:
�� ����� �������� ������� ������� ����� ����� � ����� ������-��������
�� �������� ����������� ��������� ��������� @property
������ �������� �� ��������� ����� ����� ������ ����� ������-�������� balance
ac.balance = 400000 ���������� ��������
print(ac.balance) �������� ��������
del ac.balance ������� ��������

class BankAccount:

def __init__(self, name, balance, passport):


self.__name = name
self.__balance = balance
self.__passport = passport

@property
def balance(self):
print('get_balance')
return self.__balance

@balance.setter
def balance(self,value):
print('set_balance')
if not isinstance(value,(int,float)):
raise ValueError('�������� ������� ������ ���� �����')
self.__balance = value

@balance.deleter
def balance(self):
print('delete_balance')
del self.__balance

ac = BankAccount('Alex', 1000000, 4567731654 )


print(ac.balance)
ac.balance = 400000
print(ac.balance)
print(ac.__dict__)
del ac.balance
print(ac.__dict__)
ac.balance = 700000
print(ac.__dict__)

==============================================================================

==============================================================================
������ 4
�������� property. ��������� @property
���������� property

���� ����� Square, ������ ��� ������������� ��������� �������� ����� �� ������
�������� Z
� ����� ������ �������� ������� ��������: area = Z**2 (������� �� 2 �������)

class Square:

def __init__(self, s):


self.side = s

@property
def area(self):
return self.side**2

# a = Square(5) # ������ ������� ��������


# print(a.area()) # 25 �������� ������� ���������
# a.side = 4
# print(a.area())
# �� ���������� ������� ��������� �������� �������� �����
# ������� ������ ��������� ������ ��� ���������
# ������� ������ ��������� ������ ��� �����
# �������� ����� � � ������� ����� ���� ��������� ��� � ����������
# �� ����� �� ������ ������� ������-��������
# � ��������� a.area (��� ������ '()')
# ����� ��������� ��������, ������� ������� �� ������� �������:
# ��������� �������� ������� = ��������� ��������� �������
# ������� �������� ������� = ��������� ��������� �������
# ������� �� ����� @property
# � ������ � ������� ������� ��������� ��� ����������
# � ��������� �������� � �������� �������
# �� ��������� ���������� side
b = Square(6)
print(b.area) # 36 ��������� ���������
b.side = 4
print(b.area) # 16 ��������� ���������
# � ���� ���������� ������ ��������:
# ��������� ������� �������� side �� ����� ������� � ����� 5
# ����� �������� �������� ������� b.area
# �� ��� ���� ���� ������ ����� �������� ���� ��������� ��� �� �����
# ���������� ���� � �� �� ��������, � ��� ������� � ����
# ��� �� �������� ��� ����� ��������,
# �� ������������� ��� ������� ����������� ��������
# ������� ��������:
# ��������� ��������� ��������� �������
# � ���� �������� side �� ����������
# ���������� ������ ���������, � �� �������� ��-������

������������� �����:
�������� �������� ��������� __area = None
� �������� �������� �������� ������� ���� ����������
� ���� ��� (��������) �� ���������� - ���������� ������

class Square:

def __init__(self, s):


self.side = s
self.__area = None

@property
def area(self):
if self.__area is None:
print('Calculate area')
self.__area = self.side**2
return self.__area

c = Square(7)
print(c.area) # 49 Calculate area ��������� ���������
print(c.area) # 49 ����������� ���������� ��������
# �� ��� ��������� ����� ��������:
# ��� ��������� ������� �������
# ����������� ��������� ���������
# � �� ������������ � �������� ��������
c.side = 9
print(c.area) # 49 ����������� ���������� ��������
# ��������� ���������� � side = 7
# � �� ����������� ����� � side = 9

������������� �����:
���������� ��� ������� (��������� ������� ������� = ��������� ������� �������)
�� ����� �������� ���������� self.__area ���������� ���������� � None
� ���������� � ��������� self.side ������� ��� ������ property
� �� ����� ������� ��������� ��������� self.__side
������� ������-������� @property � ��������� side (������ � ������)
class Square:

def __init__(self, s):


self.__side = s
self.__area = None

@property
def side(self):
return self.__side

@side.setter
def side(self,value):
self.__side = value
self.__area = None

@property
def area(self):
if self.__area is None:
print('Calculate area')
self.__area = self.side**2
return self.__area

c = Square(7)
print(c.area) # 49 Calculate area ��������� ���������
print(c.area) # 49 ����������� ���������� ��������
c.side = 9
print(c.area) # 81 Calculate area ��������� ���������

==============================================================================

==============================================================================
������ 4
���������� � Python

������������������ �������� - ��� ����� ������������������, ��� ������ ��������


�������
������� ����� ���� ����������, ������� ����� 0, ������ ����� 1.
���� ������������������ ����� �������� � ���� ����������� �������:
fib(x-1) + fib(x-2) if x > 1 ����� ���� ���������� ������ �� �������
����� else x ��� 0 � 1

def fib(x):
return fib(x-1) + fib(x-2) if x > 1 else x

print(fib(10)) # 55
print(fib(35)) # 9227465 �������� ����� �����, ���� �� ������ ����� (�� ����������
������)

����� ��������� ������ �������, �� ������ ��������� ������ � �������


����� ��������� ������ �������, �� ������ ��������� ������ � ������
�� ������ �����, ��� ������ ������� �������� ��������� ���
� ����� ������� 35 ������� - ������ �������� ���� ��� ������ 30 ��������� ��� �
������ ���� �� ����������� = ����� �����
������� ����������� (�����������) ��� ����������� ���������, ��� ����� �������
��������� �������� � �������� ���� ������ �������
� functools ���� ��������� ������� ��������� lru_cache � ��� ������ �����
������������ ��� ������
�� ���������� (��������) ���������� � ��� ��������� ������, � ���� �� �����������
��� �� ����� �������� ������,
� ����� ����� ���������� ��������� �������
��������� ����� ������������� : from fucntools import lru_cache
� �������������� ���� ������ : ����� �������� ��������� ��������� @lru_cache
print(fib(100)) �� ������� ������ �������� ����������� ����� ��� �������

��� �� ����� ��������� @lru_cache


���� ������ �������� �������� fib = lru_cache(fib)
�������� lru_cache ��� ���-�� ������ ������ ��������� ���������� ���� ������
���������� �����-�� ��������� � ���������� ���� ������
��� ������ ��� �������� �� �� ����� (�������������)
������� ���� ���������:
��������� ��������� - ��� ������ ��������� ��� ������
def mydec (func):
return func

������������ ���� ���� ����


@mydec
def fib(x):
return fib(x-1) + fib(x-2) if x > 1 else x

��������� ��������, �� ������ �� ������


����� ������ ��������� �������� ��������� ����� ���� �� 10
� ���������� ���������

def mydec(func):
def wrapper(x):
return func(x) * 10
return wrapper

@mydec
def fib(x):
return fib(x-1) + fib(x-2) if x > 1 else x

print(fib(10)) # 20305000000

��������� ���� �������� ������ � �������� � ����� ����������


� �� ����� ���� ������ ������ (�� �������������)
��������� :
����� ��������� �������������� ���������� ���������� ( *args, **kwargs ������
�)
� �������� ���� ���� � ����

def mydec(func):
def wrapper(*args, **kwargs):
return func(*args, *kwargs) * 10
return wrapper

@mydec
def fib(x):
return fib(x-1) + fib(x-2) if x > 1 else x

��������������� ��������� :
����� ������� ����������� ���������� � ������� cache = {}
����� ����� ����������� � ������ *args, **kwargs (������ �� �������)
(� ���������� ��� ������ �� ����� - ��������� ������)
key = str(args) + str(kwargs)
������ ���� ������ ���� key ��� � ������� cache if key not in cache:
�� ������� �������� ����
cache[key] = func(*args, *kwargs) * 10 � ���������� ��������� return
cache[key]
���� ���� �� ������ ���������� ��������� return
cache[key]

if key not in cache:


cache[key] = func(*args, *kwargs) * 10
return cache[key]

def mydec(func):
cache = {}
def wrapper(*args, **kwargs):
key = str(args) + str(kwargs)
if key not in cache:
cache[key] = func(*args, *kwargs) * 10
return cache[key]
wrapper.__doc__ = func.__doc__
wrapper.__name__ = func.__name__
return wrapper

@mydec
def fib(x):
""" �������� ������ """
return fib(x-1) + fib(x-2) if x > 1 else x

print(fib(10)) # 20305000000

print(fib.__doc__) # None ����������� ����������


print(fib.__name__) # wrapper �������� ��������� ����������

��� ����� ��������� : ����������� ���������, ����������� ���� ���� �����������


mydec, ������
������� ������
wrapper.__doc__ = func.__doc__
wrapper.__name__ = func.__name__

��� �������������� �� ����� ����������� wraps ������� ������ ��� ���������


from functools import lru_cache, wraps
� �������������� ��������� ������ wrapper ���� ����������� @wraps(func) �
������ �������� ������ ������ �������� ��������

from functools import wraps


def mydec(func):
cache = {}

@wraps(func)
def wrapper(*args, **kwargs):
key = str(args) + str(kwargs)
if key not in cache:
cache[key] = func(*args, *kwargs) * 10
return cache[key]

return wrapper

@mydec
def fib(x):
""" �������� ������ """
return fib(x-1) + fib(x-2) if x > 1 else x

print(fib(10)) # 20305000000

print(fib.__doc__) # �������� ������


print(fib.__name__) # fib

���������-������
��������� � ����������� �����������

������ : ���������� � ��������� �������� �� ������� ��������� ���� ����

@mydec - ��� ��������� (������ ����� ��������� ����� ������ � ���������� ������)
�� ��� ������ �� �������� ������� ������ @mydec(10) - ��� ��� ����� �������
� ������ ��� ������ ������� ��� :
� ��� ���� ������, ������ �� ������� � ��� ���-�� �������
� �� ��� ��� ������� � ����� ����������� ������� ���� ��������� � ����� ����
������ @mydec(n) ��� ������ ������ ���������� ��������� return decorator
� �� ��� ������ ���� � def mydec ����������� � ������ def decorator(func)
������ � ��������� ���� ����

from functools import wraps

def mydec(n):
def decorator(func):
cache = {}
@wraps(func)
def wrapper(*args, **kwargs):
key = str(args) + str(kwargs)
if key not in cache:
cache[key] = func(*args, *kwargs) * n
return cache[key]
return wrapper
return decorator

@mydec(10)
def fib(x):
""" �������� ������ """
return fib(x-1) + fib(x-2) if x > 1 else x

print(fib(10)) # 20305000000

print(fib.__doc__) # �������� ������


print(fib.__name__) # fib

���������-�����
��������� ����� ���� � �������

� ������ @Counter
���������� ������������ ������ � ������� ������ ������ Counter
� ����������� ������ def __init__(self, func) �������� ���� ����������� ����
(func -������ ��������)
� ���������� � ������� �������� ������ self.__func = func
����� ��������� �������� ����� ���� ( �����������, ��....) �� ������������
@wraps(func)
��� ���������� �������� ���� �� wrapper
������ ��� ����� ����������� �������� ���� � ������ ������, �.�. � self
(��� �������� ������� ���� ������ ����� ���������� ������� ������)
�� ����� ����� ������������ update_wrapper from functools import
lru_cache, wraps
update_wrapper(sefl, wrapped=func) sefl - ���� ����������
wrapped=func - ������ ����������

����� � � ������ @Counter �� ������� �������� ������ � ������ ���� ����


����������� �������� ������ Counter
� ����� �� ��� ���������� ����� ��� ��� ������ �� ������ �������������� �����
__call__
������� � �������� �������� ������ �� ������
����� ��� �� � ���� ���� *args, **kwargs
�� �������� ��������� � ������������ ������ � ����� *args, **kwargs
return self.__func(*args, **kwargs)
� � �������� �������� ��������: ����������� �������� ������ cnt (������ ����������
�������) self.cnt += 1

�� ��� � ��� ���� �������� ������ ������ ������ � ����� �������� ������ � ���
���������: � cnt
from functools import update_wrapper

class Counter:
cnt = 0
def __init__(self, func):
update_wrapper(self, wrapped=func)
self.__func = func

def __call__ (self, *args, **kwargs):


self.cnt += 1
return self.__func(*args, **kwargs)

@Counter
def fib(x):
""" �������� ������ """
return fib(x-1) + fib(x-2) if x > 1 else x

print(fib(10)) # 55

print(fib.__doc__) # �������� ������


print(fib.__name__) # fib

print(fib.cnt) # 177

�� ����� ������ : ����������� ����� ������������ � ��������� �� ������


������� ��������� @lru_cache
������ ����������� ��������� ��������� � ������� (� ����� ������ @lru_cache)
������ ����������� ��������� @Counter
� �.�.

from functools import lru_cache, update_wrapper

class Counter:
cnt = 0
def __init__(self, func):
update_wrapper(self, wrapped=func)
self.__func = func

def __call__ (self, *args, **kwargs):


self.cnt += 1
return self.__func(*args, **kwargs)

@Counter
@lru_cache
def fib(x):
""" �������� ������ """
return fib(x-1) + fib(x-2) if x > 1 else x

print(fib(100)) # 354224848179261915075 �������� ����� ������

print(fib.__doc__) # �������� ������


print(fib.__name__) # fib

print(fib.cnt) # 199

==============================================================================

==============================================================================
�����������
����������� ������� � ����������
��� �������� ������ ����������� ���������
��� ���������, ��������� ��� ��������� ��������

�� ������ �������� � ���, ��� �������� �������� �������� � Python

class B:
def __get__(self, obj, objtype=None):
print('__get__ b')
return obj.__dict__['_b']
def __set__ (self, obj, val):
print('__set__ b')
obj.__dict__['_b'] = val

class X:
a = 1
b = B() # ���
def __init__(self):
self.b = 5

# � ������ ������ class B - ��� ����������


# ���� � ������ ���� ������ ����� __get__ - ��� ����������� �� ������
# ���� � ������ ���� ���� �� __set__ , __del__ - ��� ���������� ������
# ��������� ����������� ������ ����, ��� �� ������
# ������ ����������� ������ �������� �� ������� �������
# � ����� ������ � obj �������� ������ �
x = X()
#X.b = B() # ��� ���
print(x.a) # 1
print(x.b) # <__main__.B object at 0x02BFB1C0> ������ �� ������ ������ B
print(x.__dict__) # {} ������� ������� x
print(X.__dict__)

����� �� ����������� ����� �������, �������� ��������-������ property

class B:
def __get__(self, obj, objtype=None):
print('__get__ b')
return obj.__dict__['_b']
def __set__ (self, obj, val):
print('__set__ b')
obj.__dict__['_b'] = val

class X:
a = 1
b = B() # ���

@property
def c(self):
print('__get__ c')
return self._c
@c.setter
def c(self,val):
print('__set__ c')
self._c = val

def __init__(self):
self.b = 5
self.c = 7

# � ������ ������ class B - ��� ����������


# ���� � ������ ���� ������ ����� __get__ - ��� ����������� �� ������
# ���� � ������ ���� ���� �� __set__ , __del__ - ��� ���������� ������
# ��������� ����������� ������ ����, ��� �� ������
# ������ ����������� ������ �������� �� ������� �������
# � ����� ������ � obj �������� ������ �
x = X()
#X.b = B() # ��� ���
print(x.a) # 1
print(x.b) # <__main__.B object at 0x02BFB1C0> ������ �� ������ ������ B
print(x.c)
print(x.__dict__) # {} ������� ������� x
print(X.__dict__)

����� ����� �� ������ ����������� ����� �� ����������� ����


� ������� ��������� ������ � ���� �� ���� �� ������ ���������
����� ������ ���������
(� ����� ������ b c)
����������� ������ ������ � ���� �� ������
� ���������� ����������
������� ������ ������������ ������

class B:
def __set_name__(self, obj, name):
print(f'__set_name__ : {name}')
self.name = '_'+ name

def __get__(self, obj, objtype=None):


print(f'__get__ : {self.name}')
return getattr(obj, self.name)

def __set__ (self, obj, val):


print(f'__set__ : {self.name}')
setattr(obj, self.name, val)

class X:
a = 1
b = B() # ���
c = B()

def __init__(self):
self.b = 5
self.c = 7

x = X()
print(x.a) # 1
print(x.b) # <__main__.B object at 0x02BFB1C0> ������ �� ������ ������ B
print(x.c)
print(x.__dict__) # {} ������� ������� x
print(X.__dict__)

������ ����� �������������� class B ������� ���������


�������� �������� ��� print �� ���� ������ �����������
� ��� �������� ����� ������� �������� ������ � ����� ��������

��� �������� ���� ���� ��������

class B:
def __init__(self, minv, maxv):
self.minv = minv
self.maxv = maxv

def __set_name__(self, obj, name):


print(f'__set_name__ : {name}')
self.name = '_'+ name

def __get__(self, obj, objtype=None):


print(f'__get__ : {self.name}')
return getattr(obj, self.name)

def __set__ (self, obj, val):

if not isinstance(val,int) or not self.minv <= val <= self.maxv:


raise ValueError(f'�������� {val} ������ ���� int � ���������
[{self.minv}:{self.maxv}]')
print(f'__set__ : {self.name}')
setattr(obj, self.name, val)

class X:
a = 1
b = B(4,7) # ���
c = B(7,9)

# ��������� ��������� ��� ���������


# � �������������� ��������
def __getattr__(self, name):
print(f'__getatt__ {name} �� ���������� � ���������� 0')
return 0

# ��������� ��������� ��� ���������


# � ����� ��������
# �� ��������� � ����� �������
# ���� �� ���������� ��������
# ������ ������� ��������� �� �������
def __getattribute__(self, name):
print(f'__getattribute___ {name}')
if name == 'c':
raise AttributeError(f'name')

return super().__getattribute__(name)

def __init__(self):
self.b = 5
self.c = 7

x = X()

x.e = 3
print(x.a) # 1
print(x.b) # <__main__.B object at 0x02BFB1C0> ������ �� ������ ������ B
print(x.c)
print(x.__dict__) # {} ������� ������� x
print(X.__dict__)
print(x.f)

����: ��� ��������� ������� � Python

���������� ���������
0. __getattribute__
���� ���������� �������� ������� ���������� ������ �� �������� (�������� ���������
����� property ���� �� �������)
���� ��� ����� �� ������� �������� ������� ���������

������ ���������

1. �������� data descriptor


�������� ������� ������ data descriptor
���� ������ �������� ��� ���������

������ ���������

2. __dict__
���� �������� � �������
���� ������ �������� ���

������� ������� �������

3. ��������
���� �������� ������ ������� ������ �� ������������
��� ���������� ��� ������ non-data descriptor
���� ������ �������� ���

�������� ���� �������� ������

4. raise AttribuetError ---> __getattr__


__getattr__ �� ���� ������������� �������
��� ���� �� �����-�� ����� ��������� ������
(� ����� ������ � __getattribute___ ���� ��� 'c' �������� ������
AttributeError(f'name')
��������� �������� __getattr__ � ����� ����)

You might also like