Python 获取类属性的属性名称

Python 获取类属性的属性名称,python,python-3.5,python-descriptors,Python,Python 3.5,Python Descriptors,以下是两个离散对象: class Field(object): pass class MyClass(object): firstname = Field() lastname = Field() email = Field() 对于任何字段对象,该对象是否有一种固有的方式可以知道分配给它的MyClass属性名 我知道我可以将参数传递给字段对象,比如email=Field(name='email'),但在我的实际情况下,这将是一个混乱和乏味的过程,所以我只是想

以下是两个离散对象:

class Field(object):
    pass

class MyClass(object):
    firstname = Field()
    lastname = Field()
    email = Field()
对于任何
字段
对象,该对象是否有一种固有的方式可以知道分配给它的
MyClass
属性名

我知道我可以将参数传递给
字段
对象,比如
email=Field(name='email')
,但在我的实际情况下,这将是一个混乱和乏味的过程,所以我只是想知道是否有一种非手动的方式来做同样的事情


谢谢

是的,您可以将
字段设置为a类,然后使用方法绑定名称。
MyClass
中不需要特殊处理

object.\uuuuu设置\u名称\uuuuu(自我、所有者、名称)
在创建所属类所有者时调用。描述符已分配给名称

这种方法是可行的

>>类字段:
...     定义设置名称(自身、所有者、名称):
...         打印(调用了“设置名称!”)
...         print(f'self:{self!r}')#这是字段实例(描述符)
...         print(f'owner:{owner!r}')#这是拥有的类(例如MyClass)
...         print(f'name:{name!r}')#描述符绑定到的名称
... 
>>>类别MyClass:
...     马铃薯=田地()
... 
__集合名称被调用!
自我:
所有者:
名字:“土豆”

有一种方法,但在我写下答案之前,我想确保您没有错误地认为这些是实例属性。它们应该在类上,而不是实例上?它们应该是类级属性,是的,不是实例属性。我意识到我的例子更适合后一种情况。道歉如果我使用的术语不正确,我相信你理解我的意思。相关:(tl;dr:很可能你做错了什么。也许你应该把这些实例存储在dict中?@Aran Fey我实际上并不想创建数量可变的变量;这个例子暗示了这一点,但它只是一个抽象概念timmy、jeff和bobby是这个场景中唯一存在的属性;它们也可以是“名字、姓氏和电子邮件”。@Aran Fey我不同意。这是ORMs中字段的标准实践,在其他几种类型的框架中都有用例。我不知道这是在3.6中添加的是的。在PEP 487之前,人们(例如Django)已经在元类/内省黑客方面做了同样的事情。+1谢谢,看起来很有希望,我很欣赏你在示例中遇到的麻烦。3.6有点前沿(我应该指定版本),但如果没有通用的答案,我会接受并升级。@Ivan我建议升级到3.6,仅用于新的
dict
实现。它们保持插入顺序,并且非常紧凑,特别是对于小型dict(由于大多数用户定义的对象都带有一个围绕d的属性,因此这些dict往往会丢弃Python程序)。
>>> 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'