Python属性和变量赋值
下面是中的一个类,用于演示Python中属性的功能 该类以摄氏度为单位设置和获取温度,并将其转换为华氏度:Python属性和变量赋值,python,python-3.x,Python,Python 3.x,下面是中的一个类,用于演示Python中属性的功能 该类以摄氏度为单位设置和获取温度,并将其转换为华氏度: class摄氏度: 定义初始值(自身,当前温度=25): 自身温度=当前温度 def至华氏温度(自身): 返回(自身温度*1.8)+32 def get_温度(自身): 打印(“获取价值”) 返回自身温度 def设置_温度(自身,值): 如果值
class摄氏度:
定义初始值(自身,当前温度=25):
自身温度=当前温度
def至华氏温度(自身):
返回(自身温度*1.8)+32
def get_温度(自身):
打印(“获取价值”)
返回自身温度
def设置_温度(自身,值):
如果值<-273:
提升值错误(“温度不可能低于-273”)
打印(“设置值”)
自身温度=50
温度=属性(获取温度、设置温度)
问题:是否self.temperature
(实例变量)实际引用了类变量temperature
?如果是,为什么
例如:
obj=摄氏度()
打印(对象温度,对象温度)
返回:
Setting value
Getting value
50 50
设定值
获得价值
50 50
我只是不明白一个具有赋值(current_temp)的实例变量如何实际引用一个类变量。如果我弄错了,对不起
self.temperature(一个实例变量)确实引用了类变量temperature吗
你指的是属性,不是变量。但是是的
如果是,为什么
因为类的实例没有temperature
属性(它们只有\u temperature
属性),所以Python在实例中找不到该属性后,也会检查该类
可能是因为\uuuu init\uuuu
方法分配给self.temperature
,所以您被甩了。但是,这不会在实例上创建temperature
属性,因为该属性是首先找到的
关于属性查找的工作原理,有很多详细的说明;它们的设计目的是使您能够执行所需的操作—例如,使property
能够工作
我只是不明白一个具有赋值(current_temp)的实例变量如何实际引用一个类变量
我在你的代码中看不到当前温度,所以我没办法
代码之所以令人困惑,部分原因在于它以一种非常不标准的方式进行操作。
属性
用于其装饰器形式,如下所示:
class Celsius:
def __init__(self, current_temp = 25):
# set the underlying value directly; don't use the property
# although you *can*, but it's arguably clearer this way
self._temperature = current_temp
def to_fahrenheit(self):
return (self.temperature * 1.8) + 32
# the getter is given the name that the property should have.
@property
def temperature(self):
print("Getting value")
return self._temperature
# The setter is "attached" to the getter with this syntax
@temperature.setter
# It doesn't matter that this has the same name, because of how the
# internal attachment logic works.
def temperature(self, value):
if value < -273:
raise ValueError("Temperature below -273 is not possible")
print("Setting value")
self._temperature = value # good idea to actually use the value!
为什么您的setter会无条件地将
self.\u temperature
设置为50
?请参阅关于Python中的实例和类变量的非常好的博客。这应该可以帮助您理解。@user2357112supportsMonica我想证明self.temperature
是通过属性设置的,而不是在初始化期间通过赋值设置的。我只是更新Python以方法解析顺序搜索类和所有祖先,寻找属性的描述符。它找到一个(属性)并调用属性的setter来处理操作。“为什么属性(名为temperature)是self.temperature的描述符?”正是因为它有这个名称。如果您使用NEW\u name
作为名称,那么您将能够执行类似self.NEW\u name=30
的操作,它将调用set\u temperature
。回答得好!下面三个问题:1)实例变量和实例属性之间的区别是什么(或类变量和类属性)?2)current\u temp
是init
的一个参数。3) “但是,这不会在实例上创建温度属性,因为首先会找到该属性”。为什么在self.temperature
分配给current\u temp
之前找到属性?1。没有“实例变量”。事实上,variable
一开始并不是Python代码的最佳术语;我们有名字,属性是名字的一种。有关更多详细信息,请尝试例如。2.哎呀,掩盖了这一点。无论如何,我希望这个想法是明确的。3.请参阅有关查找规则的链接。
class Temperature:
# Secret implementation detail: we store the value in celcius.
# We could have chosen fahrenheit instead, and do the conversions
# the other way around. Users should not call this directly.
def __init__(self, c):
# Actually, I lied. One good reason to use the property in
# the init method is to enforce bounds checking.
self.celcius = c
# We offer factory methods that let the user be explicit about
# how the initial value is provided.
@staticmethod
def in_celcius(c):
return Temperature(c)
@staticmethod
def in_fahrenheit(f):
return Temperature((f - 32) * 5/9)
# Now we define properties that let us get and set the value
# as either a celcius value or a fahrenheit one.
@property
def celcius(self):
return self._celcius
@celcius.setter
def celcius(self, c):
if c < -273:
raise ValueError("below absolute zero")
self._celcius = c
@property
def fahrenheit(self):
return (self._celcius * 9/5) + 32
@fahrenheit.setter
def fahrenheit(self, f):
# use the other property to reuse the bounds-checking logic.
self.celcius = (f - 32) * 5/9