Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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!

like image 586
Ivan Avatar asked Oct 19 '25 07:10

Ivan


1 Answers

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'
like image 112
wim Avatar answered Oct 20 '25 20:10

wim