Ivan
Ivan

Reputation: 1507

Get attribute name of class attribute

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

Answers (1)

wim
wim

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

Related Questions