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

问题描述 投票:2回答:2

我写了一个类,能够处理任意精度的整数(只是为了学习的目的)。类需要一个整数的字符串表示,并将其转换成用于进一步计算的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。该实例不能使用,因为错误类型的计算。

有没有解决这个问题的方法吗?

python oop properties
2个回答
6
投票

静态属性...?我们称之为静态属性的“属性”。这是不是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:
    ...

1
投票

现在的问题是矛盾的:staticproperty不以这种方式走在一起。在Python静态属性只是那些只分配一次,而语言本身包括大量的这些。 (大多数字符串埋葬,所有整数<一定值是预先构建的等例如the string module)。最简单的做法是施工后静态分配的属性为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映射整数构造BigInts可以像缓存和流线型构造/单储存的形式是有用的。 (例如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'

希望这可以帮助!

© www.soinside.com 2019 - 2024. All rights reserved.