对python

时间:2018-09-28 17:07:30

标签: python python-3.x oop object

我是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

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

2 个答案:

答案 0 :(得分:2)

假设您不需要实际的类属性(总在构造Foo的实例以使用该属性,并且类属性既是公共的又是逻辑上可变的,这并不常见),解决方案是使x a property包裹一个 instance 属性,该属性在实例的__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

如果确实需要将其作为类属性并且必须在实例上可以访问,则解决方案会变得很丑陋,因为您需要a metaclass来提供property类,以及类本身的其他属性,以将实例的访问权委派给类本身。

注意:强烈不鼓励实际做此事,而不是做运动

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

答案 1 :(得分:1)

可能会有所帮助。您应该按照以下方式重构类定义

class Foo():
    def __init__(self):
        self.x=0
    def check_x(self):
        if self.x > 0:
            return (self.x % 100)
        elif self.x < 0:
            return -1
p=Foo()
print(p.x) # 0
p.x=1983
p.check_x() # 83

检查负值

p.x=-100
p.check_x() # -1