首页 > 解决方案 > 在python中对类内的变量进行操作

问题描述

我是 oop 和 python 的新手。我一直在尝试做一件简单的事情:有一个名为 Foo() 的类,它包含一个名为 x 的变量,该变量最初设置为零。

>>>a = Foo()
>>>a.x
>>>0 

现在我想给 x 一个新值,所以:

>>>p.x = 1983

现在应该对 x 进行数学运算,例如将 1 添加到 x。现在 x 是 1984,所以现在当我调用 x 时:

>>> p.x
>>> 1984

程序还应该检查给 x 的值是否为负数。如果是负数,它应该返回 -1。我这样做了,但没有用:(正如我所说,它应该对 x 进行一些数学运算,运算本身并不重要)

class Foo():
    x = 0
    if x > 0:
        x %= 100
    elif x < 0:
        x = -1

我现在真的不知道我应该如何更新我提到的类变量。非常感谢您的关注。

标签: pythonpython-3.xoopobject

解决方案


假设您不需要实际的类属性(Foo无论如何,您总是在构建一个实例来使用该属性,并且类属性既是公共的又是逻辑可变的并不常见),正确的解决方案是制作x 一个property包装实例属性,每个实例都有独立的值,在__init__类的初始化程序中建立:

class Foo:
    def __init__(self):
        self._x = 0  # _x is a protected instance attr that the property uses behind the scenes

    @property
    def x(self):  # getter for x is normal
        return self._x

    @x.setter
    def x(self, newx):  # setter for x massages the value before setting it
        if newx >= 0:  # Cheaper to handle 0 on same code path as > 0 so you needn't test < 0
            newx %= 100
        else:
            newx = -1
        self._x = newx

用法很简单:

>>> myfoo = Foo()
>>> myfoo.x = 1983
>>> myfoo.x
83
>>> myfoo.x = -3748972983
>>> myfoo.x
-1

如果它确实需要是一个类属性并且它必须可以在实例上访问,那么解决方案会变得很难看,因为您需要一个元类来为类提供propertys,并在类本身上提供其他属性来将实例的访问权限委托给类本身.

注意:强烈不鼓励将其作为练习以外的任何其他方式进行

class FooMeta(type):  # Inheriting from type makes metaclass
    @property
    def x(cls):
        return cls._x
    @x.setter
    def x(cls, newx):
        if newx >= 0:
            newx %= 100
        else:
            newx = -1
        cls._x = newx

class Foo(metaclass=FooMeta):
    _x = 0
    # Must make properties on class if instances are to "benefit" from class property
    @property
    def x(self):
        return type(self).x
    @x.setter
    def x(self, newx):
        type(self).x = newx

这允许以下工作:

>>> Foo.x  # x exists on Foo itself, not just instances
>>> Foo.x = 1983
>>> Foo.x
83
>>> f = Foo()
>>> f.x  # Accessible on instances too
83
>>> f.x = -234789
>>> f.x  # Same behavior on instance
-1
>>> Foo.x  # Changing instance changed class

推荐阅读