8

我有一个类sysprops,我想在其中有一些常量。但是,我想从数据库中提取这些常量的值,所以我想在任何时候访问这些类常量之一时使用某种钩子(类似于实例变量的getattribute方法)。

class sysprops(object):
    SOME_CONSTANT = 'SOME_VALUE'

sysprops.SOME_CONSTANT  # this statement would not return 'SOME_VALUE' but instead a dynamic value pulled from the database.
4

3 回答 3

3

虽然我认为这样做是一个非常糟糕的主意,但有可能:

class GetAttributeMetaClass(type):
    def __getattribute__(self, key):
        print 'Getting attribute', key

class sysprops(object):
    __metaclass__ = GetAttributeMetaClass
于 2013-03-05T01:52:51.390 回答
2

而其他两个答案有一个有效的方法。我喜欢走“最少魔法”的路线。

您可以执行类似于元类方法的操作,而无需实际使用它们。只需使用装饰器。

def instancer(cls):
    return cls()

@instancer
class SysProps(object):
    def __getattribute__(self, key):
        return key # dummy

这将创建一个实例,SysProps然后将其分配回SysProps名称。有效地隐藏实际的类定义并允许常量实例。

由于装饰器在 Python 中更常见,我发现这种方式对于必须阅读您的代码的其他人来说更容易掌握。

于 2013-03-05T01:56:50.763 回答
0

sysprops.SOME_CONSTANTSOME_CONSTANT如果是在 上定义的属性,则可以是函数的返回值type(sysprops)

换句话说,如果sysprops是实例而不是类,您所说的通常会完成。

但这里是最重要的——类是元类的实例。所以你所知道的关于通过使用类来控制实例行为的一切都同样适用于通过使用元类来控制类的行为。

通常元类是type,但您可以通过子类化来自由定义其他元类type。如果您在元类中放置一个属性SOME_CONSTANT,那么该元类的实例,例如,sysprops当 Python 求值时将具有所需的行为sysprops.SOME_CONSTANT


class MetaSysProps(type):
    @property
    def SOME_CONSTANT(cls):
        return 'SOME_VALUE'

class SysProps(object):
    __metaclass__ = MetaSysProps


print(SysProps.SOME_CONSTANT)

产量

SOME_VALUE
于 2013-03-05T01:50:01.827 回答