繁体   English   中英

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

[英]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:
    ...

问题是矛盾的: staticproperty不会以这种方式结合在一起。 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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM