【问题标题】:Is it right to use a class' methods to update an instance of the class' variables? If it is, how do I do it?使用类的方法来更新类变量的实例是否正确?如果是,我该怎么做?
【发布时间】:2015-05-11 01:23:51
【问题描述】:

我有以下代码;

class weather(object):
temperature = 0
humidity = 0
precis = "There is no weather when there plainly should be, please contact an administrator."
cloud = "none"
windDirection = "nnw"
windSpeed = 0

def getWeather(self):
    weatherJSON = requests.get('http://www.bom.gov.au/fwo/IDT60901/IDT60901.94970.json')
    weatherDoc = json.loads(weatherJSON.text)
    temperature = weatherDoc["observations"]["data"][1]["apparent_t"]
    humidity =  weatherDoc["observations"]["data"][1]["rel_hum"]
    windDirection = weatherDoc["observations"]["data"][1]["wind_dir"]
    windSpeed = weatherDoc["observations"]["data"][1]["wind_spd_kmh"]
    cloud = weatherDoc["observations"]["data"][1]["cloud_type"]

这是一个具有天气特征的类,并包含一个更新它们的函数。如果我再用

实例化这个类
this = weather()
this.getWeather()

其中的变量不会随着真实世界的天气而更新。两个问题,为什么不呢?我想这更像是一个子问题,我这样做对吗?我的方法应该是使用类中的方法来操作类的实例吗?

【问题讨论】:

  • 附带说明,您确实应该使用一致的缩进,有时不是 2 个空格,有时是 4 个空格。它使您的代码更易于阅读和维护。

标签: python json oop object


【解决方案1】:

这里有两个基本问题。


首先,您将类属性(即由同一类的所有实例共享的变量)和普通的实例属性混合在一起——即,每个实例的一部分的变量。

你很少需要任何东西的类属性。但是,您始终需要实例属性。所以,首先:

class weather(object):
    def __init__(self):
        self.temperature = 0
        self.humidity = 0
        self.precis = "There is no weather when there plainly should be, please contact an administrator."
        self.cloud = "none"
        self.windDirection = "nnw"
        self.windSpeed = 0

注意self.temperature,而不仅仅是temperature。这就是创建实例属性的方式。这也是您访问或更新的方式。


其次,您还将局部变量(即在函数运行时存在然后消失的变量)与实例属性混合在一起。但是您已经知道从上面更新实例属性的热度。所以:

def getWeather(self):
    weatherJSON = requests.get('http://www.bom.gov.au/fwo/IDT60901/IDT60901.94970.json')
    weatherDoc = json.loads(weatherJSON.text)
    self.temperature = weatherDoc["observations"]["data"][1]["apparent_t"]
    self.humidity =  weatherDoc["observations"]["data"][1]["rel_hum"]
    self.windDirection = weatherDoc["observations"]["data"][1]["wind_dir"]
    self.windSpeed = weatherDoc["observations"]["data"][1]["wind_spd_kmh"]
    self.cloud = weatherDoc["observations"]["data"][1]["cloud_type"]
    self.precis = '???'

(我不确定您要在 precis 中输入什么,但显然您不想将其保留为“没有天气……”。)


如果您在没有第一个修复的情况下进行了第二个修复,那么一切都会看起来正常工作,但这只是巧合。当你请求this.temperature时,如果this没有名为temperature的实例属性,Python会自动寻找类属性type(this).temperature。如果您随后添加一个名为 temperature 的实例属性,它会“隐藏”类属性,因此下次您执行 this.temperature 时,您将获得实例的值。

因此,您可以将类属性用作实例属性的一种“默认值”。但是,只有在您知道自己在做什么的情况下,您才应该这样做。 (如果你开始使用像列表这样的可变值并在你的方法中改变它们,这会变得非常混乱......)

【讨论】:

    【解决方案2】:

    两个问题,为什么不呢,我想作为一个子问题,我这样做对吗?

    您正在更新 getWeather() 中的局部变量。

    你应该更新实例变量,这可以通过在变量名前加上 self 来完成,换句话说,替换:

    def getWeather(self):
        ...
        cloud = ...
    

    def getWeather(self):
        ...
        self.cloud = ...
    

    【讨论】:

      【解决方案3】:

      您的示例中的缩进是否损坏?这些变量应该是天气类的类成员吗?

      不管怎样,该函数遮蔽它们,在本地创建新的,因此不会改变其他的。

      【讨论】:

      • 这不是一个真正的答案,要求澄清可能最好作为评论完成
      • 另外,该函数实际上并没有隐藏类属性。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-07-24
      • 2013-01-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多