如何创建返回类本身实例的静态类属性?

2024-04-26 11:00:56 发布

您现在位置:Python中文网/ 问答频道 /正文

我写了一个类,可以处理任意精度的整数(只是为了学习的目的)。该类接受整数的字符串表示形式,并将其转换为BigInt的实例以供进一步计算。你知道吗

很多时候你需要数字0和1,所以我想如果这个类能返回这些数字会很有帮助。我尝试了以下方法:

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更改为一个属性,但是由于使用了decorator,因此编写BigInt.zero返回类property的实例,而不是BigInt。由于类型错误,该实例不能用于计算。你知道吗

有办法解决这个问题吗?你知道吗


Tags: 实例方法selfnoneinitvaluedef错误
2条回答

静态属性。。。?我们称静态属性为“属性”。这不是Java,Python是一种动态类型化的语言,这样的构造会使事情变得过于复杂。你知道吗

只需设置一个类属性:

class BigInt: 
    def __init__(self, value): 
        ... 

BigInt.zero = BigInt("0")

如果您希望它完全在类中定义,那么可以使用decorator进行定义(但请注意,这只是编写相同内容的一种更为奇特的方式)。你知道吗

def add_zero(cls):
    cls.zero = cls("0")
    return cls

@add_zero
class BigInt:
    ...

这个问题是矛盾的:staticproperty不是以这种方式结合在一起的。Python中的Static属性是只分配一次的属性,而语言本身包含大量这些属性。(大多数字符串被中断,所有整数<;特定值被预先构造,等等,例如the ^{} module)。最简单的方法是在构建之后静态地分配属性,如wim所示:

class Foo:
    ...

Foo.first = Foo()
...

或者,正如他进一步建议的,使用类装饰器来执行赋值,这在功能上与上面的相同。实际上,decorator是一个以“decorated”函数作为参数的函数,它必须返回一个函数来有效地替换原来的函数。这可能是原始函数,例如,用一些注释修改,也可能是一个完全不同的函数。原始(修饰的)函数可以被调用,也可以不被调用。你知道吗

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:
    ...

如果目的是在公共整数值上节省一些时间,那么^{}将整数映射到构造的BigInt可以作为缓存和简化的构造/单例存储的一种形式。(例如BigInt.numbers[27]

然而,在类级别使用@property的问题引起了我的兴趣,所以我做了一些挖掘。如果将属性推到对象模型层次结构上的元类,那么在类级别使用“descriptor protocol objects”(由@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'

希望这有帮助!你知道吗

相关问题 更多 >