Reputation: 1507
Here are two discrete objects:
class Field(object):
pass
class MyClass(object):
firstname = Field()
lastname = Field()
email = Field()
For any Field
object, is there inherently a way for that object to be aware of the attribute name that MyClass
assigned it?
I know I could pass parameters to the Field
object, like email = Field(name='email')
, but that would be messy and tedious in my actual case so I'm just wondering if there's a non-manual way of doing the same thing.
Thanks!
Upvotes: 4
Views: 3473
Reputation: 362607
Yes, you can make the Field
class a descriptor, and then use __set_name__
method to bind the name. No special handling is needed in MyClass
.
object.__set_name__(self, owner, name)
Called at the time the owning class owner is created. The descriptor has been assigned to name.
This method is available in Python 3.6+.
>>> class Field:
... def __set_name__(self, owner, name):
... print('__set_name__ was called!')
... print(f'self: {self!r}') # this is the Field instance (descriptor)
... print(f'owner: {owner!r}') # this is the owning class (e.g. MyClass)
... print(f'name: {name!r}') # the name the descriptor was bound to
...
>>> class MyClass:
... potato = Field()
...
__set_name__ was called!
self: <__main__.Field object at 0xcafef00d>
owner: <class '__main__.MyClass'>
name: 'potato'
Upvotes: 8