python是否有类似于_usetattr__;但用于python类的方法?

python是否有类似于_usetattr__;但用于python类的方法?,python,Python,目前,\uuuuu setattr\uuuuu仅适用于例如。课堂上有没有类似的方法?我问这个问题是因为当用户在类中定义属性时,我想按顺序收集已定义属性的列表,如下所示: class CfgObj(object): _fields = [] def __setattr__(self, name, value): self._fields.append([name, value]) object.__setattr__(self, name, valu

目前,\uuuuu setattr\uuuuu仅适用于例如。课堂上有没有类似的方法?我问这个问题是因为当用户在类中定义属性时,我想按顺序收集已定义属性的列表,如下所示:

class CfgObj(object):
    _fields = []
    def __setattr__(self, name, value):
        self._fields.append([name, value])
        object.__setattr__(self, name, value)

class ACfg(CfgObj):
    setting1 = Field(str, default='set1', desc='setting1 ...')
    setting2 = Field(int, default=5, desc='setting2...')
acfg = ACfg()
acfg.c = 1
acfg._fields == [['c', 1]]
我知道上面的代码不会像预期的那样工作,因为\uuu setattr\uuu仅通过实例调用,如下所示:

class CfgObj(object):
    _fields = []
    def __setattr__(self, name, value):
        self._fields.append([name, value])
        object.__setattr__(self, name, value)

class ACfg(CfgObj):
    setting1 = Field(str, default='set1', desc='setting1 ...')
    setting2 = Field(int, default=5, desc='setting2...')
acfg = ACfg()
acfg.c = 1
acfg._fields == [['c', 1]]
那么,python类是否有任何等价的\uuuu setattr\uuuu?主要目的是当用户在类中定义定义属性时,按顺序收集该属性。

是,但是


如果在类的元类上定义了
\uuuu setattr\uuuuu()
,则在设置类的属性时将调用它,但仅在创建类之后:

>>> class Meta(type):
...     def __setattr__(cls, name, value):
...         print "%s=%r" % (name, value)
... 
>>> class A(object):
...     __metaclass__ = Meta
... 
>>> A.a = 1
a=1
但在定义类时它不起作用,所以它可能不是您想要的


在元类
\uuuu init\uuuuu()
中获取类属性是可行的,但是您失去了定义的顺序(以及多个定义).

要解决您的问题(但不是您的问题),我要做的是设置字段创建的时间戳创建
字段
对象的计数器,并将计数器的当前值设置为创建的值:

class Field(object):
    count = 0
    def __init__(self, value, default=None, desc=None):
        self.value = value
        self.default = default
        self.desc = desc
        # Here comes the magic
        self.nth = Field.count
        Field.count += 1
        # self.created_at = time.time()
然后,我将创建一个方法,用于返回按其计数器值排序的所有字段:

class CfgObj(object):
    def params(self):
        ns = dir(self)
        fs = [getattr(self, field) 
                    for field in ns 
                    if isinstance(getattr(self, field), Field)]
        # fs = sorted(fs, key=lambda f: f.created_at)
        fs = sorted(fs, key=lambda f: f.nth)
        return fs
它的用法很直观:

class ACfg(CfgObj):
    setting1 = Field(str, default='set1', desc='setting1 ...')
    setting2 = Field(int, default=5, desc='setting2...')

print ACfg().params()

显然,字段是按对象创建时间排序的,而不是按字段创建时间排序的,但这对您来说已经足够了。是吗?

你想干什么?你能举个例子吗?看看Django使用表单的方式。这是好东西。在
字段
中放置一个计数器,这样每个实例都会获得一个ID,并使用一个元类将该计数器的字段排序为
\u字段
。我想创建一个到xml配置文件的配置类映射,同时使用该类生成一个GUI,供用户更改值。我希望GUI按照它们定义的顺序生成设置,否则使用python dict将不会保留顺序。在这种情况下使用时间是不明智的(您能保证它们是不同的吗?)或者是必要的。我会像Django那样做-在
字段
类中有一个计数器,每个实例的计数器都会递增,然后进行比较。然后使用一个元类将其自动放入类中(这样你就可以只做
ACfg().fields
,它将是一个按正确顺序排列的字段列表)。我更新了我的答案(但没有使用元类,因为我的偏见认为它们是邪恶的:D)谢谢,非常感谢!!这正是我想要的。虽然字段计数器会很大,因为我会有很多类创建相同的字段,但我看不出有什么大问题。我从来没有想过用这些技巧来解决这个问题……这不是我想要的,但很高兴知道元类有这种能力。