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

Python 如何创建返回类本身实例的静态类属性?,python,oop,properties,Python,Oop,Properties,我写了一个类,可以处理任意精度的整数(只是为了学习)。该类接受整数的字符串表示形式,并将其转换为BigInt的实例以进行进一步计算 通常情况下,您需要数字0和1,因此我认为如果该类可以返回这些数字,将非常有用。我尝试了以下方法: class BigInt(): zero = BigInt("0") def __init__(self, value): ####yada-yada#### class BigInt(): __zero = None

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

通常情况下,您需要数字01,因此我认为如果该类可以返回这些数字,将非常有用。我尝试了以下方法:

class BigInt():
    zero = BigInt("0")

    def __init__(self, value):
        ####yada-yada####
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####
这不管用。错误:“未定义名称“BigInt”

然后我尝试了以下方法:

class BigInt():
    zero = BigInt("0")

    def __init__(self, value):
        ####yada-yada####
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
返回类
属性的实例,而不是
BigInt
。由于类型错误,该实例无法用于计算


有办法解决这个问题吗?

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

只需执行此操作,设置类属性:

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

BigInt.zero = BigInt("0")
如果您希望它完全在类中定义,那么可以使用decorator进行定义(但请注意,这只是编写相同内容的一种更奇特的方式)


问题是矛盾的:
static
property
没有以这种方式结合在一起。Python中的静态属性只是一次分配的属性,而语言本身包含大量的静态属性。(大多数字符串是嵌入的,所有<某个值的整数都是预先构造的,等等,例如…)。最简单的方法是在构建后静态分配属性,如wim所示:

Foo类:
...
Foo.first=Foo()
...
或者,正如他进一步建议的那样,使用类装饰器来执行赋值,其功能与上述相同。decorator实际上是一个函数,它以“装饰”函数作为参数给定,并且必须返回一个函数来有效地替换原来的函数。这可能是原始函数,比如说,通过一些注释进行修改,也可能是一个完全不同的函数。原始(修饰的)函数可能会被调用,也可能不会被调用

def预加载(**值):
def内部(cls):
对于k,v,在values.items()中:
设置属性(cls、k、cls(v))
返回cls
返回内部
然后可以动态地使用它:

@预加载(零=0,一=1)
Foo类:
...
如果目的是为了节省一些关于公共整数值的时间,那么将整数映射到构造的
BigInt
s可以作为缓存和精简的构造/单例存储的一种形式。(例如,
BigInt.number[27]

然而,在类级别使用
@property
的问题引起了我的兴趣,所以我做了一些挖掘。如果将属性推到对象模型层次结构上的元类,则完全可以在类级别使用“”(属性
@decorator返回该属性)

Foo类(类型):
@财产
def bar(cls):
打印(“我是一个”,cls)
返回27
类栏(元类=Foo):
...
>>>酒吧
我是一名医生
>Bar().Bar
AttributeError:“Bar”对象没有属性“Bar”

希望这有帮助

你不能创建一个继承该类的类吗。因此,实例化子类时,它可以使用父类的活动实例返回自身,并将值设置为
“0”
class initator(BigInt):def\uuuu init\uuuuu(self):super(initator,self)。\uuuu init\uuuu8“
。我大体上同意,
static
属性
结合只是一个固定值的属性。然而,在类级别拥有real
@property
属性(描述符协议属性)这一更普遍的问题很有趣,应该通过将这样的描述符对象分配给元类来实现。(不过,我还没有测试过它。它还使它只能从类级别访问,而不能从实例级别访问。)谢谢!我不认为这是显而易见的,但是来自其他语言的python方法有时很难理解。你能解释一下如何与装饰师合作吗?我尝试了以下导致递归深度错误的操作:
def big_int_decorator(cl):def wrapper(*args):value=cl(*args)value.z=BigInt(“0”)返回值返回wrapper
@wim非常感谢!您用元类描述的内容更像是classmethod的属性,而不是staticmethod的属性。这里详细讨论了这种做法和所有相关的陷阱:@wim这个问题有14个答案,最上面的答案提到了Python2.2(超越古代),并且没有提供完整的功能(没有setter/deleter),第二个投票最多的答案提到了元类,没有指出通过实例访问的重要问题,一个数字使用
@property
w/从实例访问,这与我在这里要说的完全相反,等等。您是否可以指出具体的注意事项?(虽然是的,但从技术上讲,这更像是一个属性
classmethod
,而不是
staticmethod
)答案是错误的,原因在评论中讨论过。这看起来不错。