class SetNames:
def __init__(self, names):
self.names = []
self.results = dict()
self.add(names)
def __call__(self, surname):
result = self.results.get(surname)
if self.results == dict():
self.results.update({surname: []})
for name in self.names:
self.results[surname].append(
f'{name} {surname}'
)
result = self.results[surname]
return result
def add(self, lst: list):
for i in lst:
if not isinstance(i, str):
raise TypeError(
'Имена должны быть строками'
)
self.results.clear()
self.names.extend(lst)
girl_names = SetNames(('Julia', 'Lisa'))
girl_names.add(['Inna', 'Anna'])
print(girl_names('Koval'))
# ['Julia Koval', 'Lisa Koval', 'Inna Koval', 'Anna Koval']
Функтор лишен проблем с поздним связыванием, характерных для замыканий.
КЛАССЫ-ДЕКОРАТОРЫ
Поскольку функторы можно вызывать, напрашивается использование их классов в роли декораторов.
from datetime import datetime
class Validation:
def __init__(self, function):
self.function = function
def __call__(self, *args, **kwargs):
res = self.function(*args, **kwargs)
if not 0 < res < 100:
raise ValueError(
'Validation failed'
)
return f'{datetime.now()}: {res}'
@Validation
def square(a):
return a**2
print(square(8))
# 2022-10-29 09:24:29.503697: 64
print(square(12))
# ValueError: Validation failed
Конструктор нашего класса-декоратора принимает только один аргумент - функцию. В методе __call__ мы проверяем, находится ли возвращаемое значение в диапазоне от 0 до 100. Если условие не выполняется, мы вызываем ошибку, а иначе просто возвращаем строку с текущим временем и полученным числом. Но можно пойти дальше, и сделать декоратором объект класса.
Достарыңызбен бөлісу: |