对python中类内变量的操作 [英] operation on a variable inside a class in 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 property
s 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屋!