#python
#python
Вопрос:
Вчера я видел твит от Raymond Hettinger . Он использовал __set_name__
.
Когда я объявляю __set_name__
для своего класса, имя становится именем экземпляра. Владельцем стал Foo
, что и ожидалось, но я не мог понять, когда и как это полезно.
class Bar:
def __set_name__(self, owner, name):
print(f'{self} was named {name} by {owner}')
class Foo:
x = Bar()
y = Bar()
Это печатает
<__main__.Bar object at 0x7f48f2968820> was named x by <class '__main__.Foo'>
<__main__.Bar object at 0x7f48f2968c70> was named y by <class '__main__.Foo'>
Комментарии:
1. Обычно это используется с протоколом дескриптора. Это полезно, потому что часто дескрипторы хотят знать имя переменной, которой они назначены. Ранее вам нужно было бы указать это имя, например
x = Bar('x')
, например. Это просто удобство для этого.
Ответ №1:
Как @juanpa предоставил краткое объяснение, он используется для определения имени и класса переменной. Один из его вариантов использования — для ведения журнала. Когда вы хотите записать имя переменной. Этот пример был в руководстве по описанию.
import logging
logging.basicConfig(level=logging.INFO)
class LoggedAccess:
def __set_name__(self, owner, name):
self.public_name = name
self.private_name = '_' name
def __get__(self, obj, objtype=None):
value = getattr(obj, self.private_name)
logging.info('Accessing %r giving %r', self.public_name, value)
return value
def __set__(self, obj, value):
logging.info('Updating %r to %r', self.public_name, value)
setattr(obj, self.private_name, value)
class Person:
name = LoggedAccess() # First descriptor instance
age = LoggedAccess() # Second descriptor instance
def __init__(self, name, age):
self.name = name # Calls the first descriptor
self.age = age # Calls the second descriptor
def birthday(self):
self.age = 1