对python中类内变量的操作 [英] operation on a variable inside a class in python

查看:41
本文介绍了对python中类内变量的操作的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

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

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

>>>p.x = 1983

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

<预><代码>>>>像素>>>1984年

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

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

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

解决方案

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

 Foo 类:def __init__(self):self._x = 0 # _x 是一个受保护的实例属性,该属性在幕后使用@财产def x(self): # getter for x 是正常的返回 self._x@x.setterdef x(self, newx): # setter for x 在设置之前对值进行按摩if newx >= 0: # 在与 > 相同的代码路径上处理 0 更便宜0 所以你不需要测试 <0新 %= 100别的:新x = -1self._x = newx

用法非常简单:

<预><代码>>>>myfoo = Foo()>>>myfoo.x = 1983>>>myfoo.x83>>>myfoo.x = -3748972983>>>myfoo.x-1

如果它真的需要是一个类属性并且它必须在实例上可以访问,那么解决方案就会变得丑陋,因为你需要 一个元类,用于提供类的property,以及类本身的附加属性以委托对实例的访问到类本身.

注意:强烈不鼓励实际将其作为练习以外的任何事情:

class FooMeta(type): # 继承 type 使得元类@财产定义 x(cls):返回 cls._x@x.setterdef x(cls, newx):如果 newx >= 0:新 %= 100别的:新x = -1cls._x = newx类 Foo(元类 = FooMeta):_x = 0# 如果实例要从类属性中受益",则必须在类上创建属性@财产def x(self):返回类型(self).x@x.setterdef x(self, newx):type(self).x = newx

这允许以下工作:

<预><代码>>>>Foo.x # x 存在于 Foo 本身,而不仅仅是实例>>>Foo.x = 1983>>>foo.x83>>>f = Foo()>>>f.x # 也可以在实例上访问83>>>f.x = -234789>>>f.x # 实例上的相同行为-1>>>Foo.x # 改变实例改变类

I'm new with oop and python. I've been trying to do a simple thing: there is class called Foo(),it contains a variable called x which is initially set to zero.

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

now I want to give a new value to x so:

>>>p.x = 1983

now a math operation should happen to x, for instance 1 is add to x.now x is 1984,so now when I call x:

>>> p.x
>>> 1984

also the program should check that whether or not the value given to x is negative or not.If it is negative it should return -1. I did this but it didn't work:(as I said it should do some mathematical operation on x,the operation itself is not really important)

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

I really don't now how should I update a class variable in they I mentioned. Thank you very much for your attention.

解决方案

Assuming you don't need actual class attributes (you're always constructing an instance of Foo to use the attribute anyway, and it's not common for class attributes to be both public and logically mutable), the correct solution is to make x a property that wraps an instance attribute, which has independent values per instance, established in the __init__ initializer for the class:

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

Usage is pretty simple:

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

In case it really needs to be a class attribute and it must be accessible on instances, the solution gets ugly, as you need a metaclass to provide propertys on classes, and additional properties on the class itself to delegate access on instances to the class itself.

Note: I strongly discourage actually doing this as anything other than an exercise:

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

That allows the following to work:

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

这篇关于对python中类内变量的操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆