我有一个类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.
答案 0 :(得分:2)
虽然其他两个答案都有一个有效的方法。我喜欢采用“最少魔法”的路线。
您可以在不实际使用它们的情况下执行类似于元类方法的操作。只需使用装饰器。
def instancer(cls):
return cls()
@instancer
class SysProps(object):
def __getattribute__(self, key):
return key # dummy
这将创建SysProps
的实例,然后将其分配回SysProps
名称。有效地遮蔽实际的类定义并允许一个常量实例。
由于装饰器在Python中比较常见,我发现这种方式对于那些必须阅读代码的人来说更容易掌握。
答案 1 :(得分:1)
虽然我认为这样做是非常的坏主意,但有可能:
class GetAttributeMetaClass(type):
def __getattribute__(self, key):
print 'Getting attribute', key
class sysprops(object):
__metaclass__ = GetAttributeMetaClass
答案 2 :(得分:0)
sysprops.SOME_CONSTANT
是SOME_CONSTANT
上定义的属性,则 type(sysprops)
可以是函数的返回值。
换句话说,如果sysprops
是一个实例而不是一个类,那么你所说的通常就是这样做的。
但是这里是踢球者 - 类是元类的实例。因此,您通过使用类来控制实例行为的所有知识同样适用于通过使用元类来控制类的行为。
通常,元类是type
,但您可以通过子类type
自由定义其他元类。如果在属性类中放置属性SOME_CONSTANT
,那么该元类的实例,例如当Python评估sysprops
时,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