Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/326.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python属性和变量赋值_Python_Python 3.x - Fatal编程技术网

Python属性和变量赋值

Python属性和变量赋值,python,python-3.x,Python,Python 3.x,下面是中的一个类,用于演示Python中属性的功能 该类以摄氏度为单位设置和获取温度,并将其转换为华氏度: class摄氏度: 定义初始值(自身,当前温度=25): 自身温度=当前温度 def至华氏温度(自身): 返回(自身温度*1.8)+32 def get_温度(自身): 打印(“获取价值”) 返回自身温度 def设置_温度(自身,值): 如果值

下面是中的一个类,用于演示Python中属性的功能

该类以摄氏度为单位设置和获取温度,并将其转换为华氏度:

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