[英]How to create a static class property that returns an instance of the class itself?
我编写了一个可以处理任意精度整数的类(仅用于学习目的)。 该类采用整数的字符串表示形式,并将其转换为BigInt
实例以进行进一步计算。
通常你需要数字零和一 ,所以我认为如果课程可以返回这些将是有帮助的。 我尝试了以下方法:
class BigInt():
zero = BigInt("0")
def __init__(self, value):
####yada-yada####
这不起作用。 错误:“名称'BigInt'未定义”
然后我尝试了以下内容:
class BigInt():
__zero = None
@staticmethod
def zero():
if BigInt.__zero is None:
BigInt.__zero = BigInt('0')
return BigInt.__zero
def __init__(self, value):
####yada-yada####
这实际上非常有效。 我不喜欢的是zero
是一个方法(因此必须用BigInt.zero()
调用),这是违反直觉的,因为它应该只引用一个固定值。
所以我尝试将zero
更改为属性,但是然后编写BigInt.zero
返回类property
的实例而不是BigInt
因为使用了装饰器。 由于类型错误,该实例不能用于计算。
有没有解决这个问题的方法?
静态属性......? 我们将静态属性称为“属性”。 这不是Java,Python是一种动态类型语言,这样的构造实际上会使问题过于复杂。
只需这样做,设置一个类属性:
class BigInt:
def __init__(self, value):
...
BigInt.zero = BigInt("0")
如果您希望将它完全封装在类块中,请使用类装饰器(但请注意,这只是编写相同内容的一种更奇特的方式)。
def add_zero(cls):
cls.zero = cls("0")
return cls
@add_zero
class BigInt:
...
问题是矛盾的: static
和property
不会以这种方式结合在一起。 Python中的静态属性只是一次分配的,而语言本身包含了大量的静态属性 。 ( 大多数字符串是内部的,所有整数<某个值都是预先构造的,等等。例如string
模块 。)。 最简单的方法是在构造之后静态分配属性,如wim所示:
class Foo:
...
Foo.first = Foo()
...
或者,正如他进一步建议的那样,使用类装饰器来执行赋值,这在功能上与上面相同。 实际上,装饰器是一个赋予“装饰”函数作为参数的函数,并且必须返回一个函数来有效地替换原始函数。 这可能是原始功能,例如,使用某些注释修改,或者可能是完全不同的功能。 可以或不可以调用原始(修饰)函数以适合装饰器。
def preload(**values):
def inner(cls):
for k, v in values.items():
setattr(cls, k, cls(v))
return cls
return inner
然后可以动态使用它:
@preload(zero=0, one=1)
class Foo:
...
如果目的是在常用整数值上节省一些时间,则将defaultdict
映射整数映射到构造的BigInt
可以作为缓存和简化构造/单例存储的一种形式。 (例如BigInt.numbers[27]
)
但是,在课堂级别使用@property
的问题引起了我的兴趣,所以我做了一些挖掘。 如果你将对象模型层次结构中的属性放到元类中,完全可以在类级别使用“ 描述符协议对象 ”( @property
装饰器返回)。
class Foo(type):
@property
def bar(cls):
print("I'm a", cls)
return 27
class Bar(metaclass=Foo):
...
>>> Bar.bar
I'm a <class '__main__.Bar'>
<<< 27
值得注意的是,无法从实例访问此属性:
>>> Bar().bar
AttributeError: 'Bar' object has no attribute 'bar'
希望这可以帮助!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.