19

假设我有这样的课程:

class Alphabet(object):
     __init__(self):
         self.__dict = {'a': 1, 'b': 2, ... 'z': 26}

     @property
     def a(self):
         return self.__dict['a']

     @property
     def b(self):
         return self.__dict['b']

     ...

     @property
     def z(self)
         return self.__dict['z']

这将是一项漫长而繁琐的定义任务,而且似乎非常多余。有没有办法动态创建这些属性?我知道您可以使用内置的 setattr 动态创建属性,但我想控制读/写/删除访问(因此我想使用属性)。谢谢!

4

2 回答 2

37

不要使用属性,但要实现以下方法:

  • __getattr__(self, name)
  • __setattr__(self, name, value)
  • __delattr__(self, name)

请参阅http://docs.python.org/reference/datamodel.html#customizing-attribute-access

您的__getattr__方法可能如下所示:

def __getattr__(self, name):
    try:
        return self.__dict[name]
    except KeyError:
        msg = "'{0}' object has no attribute '{1}'"
        raise AttributeError(msg.format(type(self).__name__, name))
于 2012-06-10T09:26:05.813 回答
-1

不要那样做。让班级的消费者__dict直接上台,并相信他们不会搞砸。请记住,我们在这里都是同意的成年人!

Ned Batchelder 解释得比我还好:


将数据保留在变量名之外

这个问题让我想起了我在 Stack Overflow 或 #python IRC 频道中看到的其他人:

  • 如何查看变量是否存在?
  • 如何使用一个变量作为另一个变量的名称?
  • 如何使用变量作为 SQL 表名的一部分?

所有这些的共同点是试图弥合两个域之间的差距:程序中的数据,以及程序中数据的名称。任何时候发生这种情况,这都是一个明确的信号,表明您需要在数据建模中提升一个级别。您需要一本字典,而不是 26 个列表。而不是 N 个表,您应该有一个表,其中还有一列。

于 2012-06-10T10:07:42.953 回答