在不经过 __setattr__ 的情况下创建类属性

2 投票
1 回答
521 浏览
提问于 2025-04-15 23:51

下面是我创建的一个类,用来方便地存储一堆数据作为属性。这些数据最终会被存储在一个字典里。我重写了 __getattr____setattr__ 方法,以便能以不同的单位来存取这些值。

当我开始重写 __setattr__ 方法时,我在 __init__ 的第二行创建那个初始字典时遇到了麻烦,像这样...

super(MyDataFile, self).__setattr__('_data', {})

我的问题是... 有没有更简单的方法来创建一个类级别的属性,而不需要通过 __setattr__?另外,我是否应该担心保持一个单独的字典,还是说我可以把所有东西都存储在 self.__dict__ 里?

#!/usr/bin/env python

from unitconverter import convert
import re

special_attribute_re = re.compile(r'(.+)__(.+)')

class MyDataFile(object):

    def __init__(self, *args, **kwargs):
        super(MyDataFile, self).__init__(*args, **kwargs)
        super(MyDataFile, self).__setattr__('_data', {})

    #
    # For attribute type access
    #
    def __setattr__(self, name, value):
        self._data[name] = value

    def __getattr__(self, name):

        if name in self._data:
            return self._data[name]

        match = special_attribute_re.match(name)
        if match:
            varname, units = match.groups()
            if varname in self._data:
                return self.getvaras(varname, units)

        raise AttributeError

    #
    # other methods
    #
    def getvaras(self, name, units):
        from_val, from_units = self._data[name]
        if from_units == units:
            return from_val
        return convert(from_val, from_units, units), units

    def __str__(self):
        return str(self._data)



d = MyDataFile()

print d

# set like a dictionary or an attribute
d.XYZ = 12.34, 'in'
d.ABC = 76.54, 'ft'

# get it back like a dictionary or an attribute
print d.XYZ
print d.ABC

# get conversions using getvaras or using a specially formed attribute
print d.getvaras('ABC', 'cm')
print d.XYZ__mm

1 个回答

0

你在例子中的 __setattr__ 其实没什么用,只是把东西放到了 _data 里,而不是放到 __dict__ 里。把它删掉吧。

把你的 __getattr__ 改成使用 __dict__

把你的值和单位存成一个简单的二元组(2-tuple)。

撰写回答