Python 为什么该类变量即使已初始化也为None?

Python 为什么该类变量即使已初始化也为None?,python,kivy,Python,Kivy,我正在学习Kivy,如果这段代码的目的是缓存一个小部件,但我很难理解它到底发生了什么: class WeatherRoot(BoxLayout): current_weather = ObjectProperty() def show_current_weather(self, location=None): self.clear_widgets() print(WeatherRoot.current_weather) prin

我正在学习Kivy,如果这段代码的目的是缓存一个小部件,但我很难理解它到底发生了什么:

class WeatherRoot(BoxLayout):
    current_weather = ObjectProperty()

    def show_current_weather(self, location=None):
        self.clear_widgets()

        print(WeatherRoot.current_weather)
        print(self.current_weather)

        if location is None and self.current_weather is None:
            location = 'New York (US)'

        if location is not None:
            self.current_weather = Factory.CurrentWeather()
            self.current_weather.location = location
        self.add_widget(self.current_weather)
问题是,
current\u weather
,据我所知,这是一个类变量,被定义为一个
ObjectProperty
,因为我没有一个实例变量(我想是这样)覆盖这个变量,当我引用
self.current\u weather
时,我引用的是类变量,因此,我认为
self.current_weather
WeatherRoot.current_weather
相同,但不是因为当我打印这些变量时,我希望它们都是
ObjectProperty
实例,我得到:

<ObjectProperty name=current_weather>
None
因此,当我按下“取消”按钮并且之前没有搜索任何位置时,默认值是硬编码的,因为它可以在纽约(美国)看到。当我以前搜索过某个位置并按下“取消”按钮时,将显示该位置

有人能解释一下这个变量是怎么回事吗?我以为不需要这个类变量,但当我删除它时,我的应用程序崩溃了

如果您需要,以下是我的全部代码:

import json

from kivy.app import App
from kivy.network.urlrequest import UrlRequest
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.listview import ListItemButton
from kivy.factory import Factory

class WeatherRoot(BoxLayout):
    current_weather = ObjectProperty()

    def show_current_weather(self, location=None):
        self.clear_widgets()

        print(WeatherRoot.current_weather)
        print(self.current_weather)

        if location is None and self.current_weather is None:
            location = 'New York (US)'

        if location is not None:
            self.current_weather = Factory.CurrentWeather()
            self.current_weather.location = location
        self.add_widget(self.current_weather)

    def show_add_location_form(self):
        self.clear_widgets()
        self.add_widget(AddLocationForm())


class LocationButton(ListItemButton):
    pass


class AddLocationForm(BoxLayout):
    search_input = ObjectProperty()
    search_results = ObjectProperty()

    def search_location(self):
        search_template = 'http://api.openweathermap.org/' \
                          'data/2.5/find?q={}&type=like&APPID=' \
                          '090428d02304be901047796d430986e3'
        search_url = search_template.format(self.search_input.text)
        print(search_url)
        request = UrlRequest(search_url, self.found_location)

    def found_location(self, request, data):
        data = json.loads(data.decode()) if not isinstance(data, dict) else data
        cities = ['{} ({})'.format(d['name'], d['sys']['country'])
                  for d in data['list']]
        # self.search_results.item_strings = cities
        self.search_results.adapter.data.clear()
        self.search_results.adapter.data.extend(cities)
        self.search_results._trigger_reset_populate()


class WeatherApp(App):
    pass


WeatherApp().run()

属性是。虽然它们是在类级别定义的,但它们具有实例级别的行为,并且在一级近似情况下,它们的行为类似于实例变量。

属性是。虽然是在类级别定义的,但它们具有实例级别的行为,并且在一级近似情况下,它们的行为将类似于实例变量。

当您说属性是描述符时,您是说Kivy属性被定义为描述符?或者你的意思是它们是Python属性,也就是说,一个可以像访问属性一样访问的方法?Kivy属性是描述符,因为它们实现了链接文档中的描述符协议。它们在行为方式上与普通python属性类似,但它们的实现不同(它们包括额外的行为)?或者你的意思是它们是Python属性,也就是说,一个可以像访问属性一样访问的方法?Kivy属性是描述符,因为它们实现了链接文档中的描述符协议。它们的行为方式类似于普通的python属性,但它们的实现不同(它们包括额外的行为)。
import json

from kivy.app import App
from kivy.network.urlrequest import UrlRequest
from kivy.properties import ObjectProperty
from kivy.uix.boxlayout import BoxLayout
from kivy.uix.listview import ListItemButton
from kivy.factory import Factory

class WeatherRoot(BoxLayout):
    current_weather = ObjectProperty()

    def show_current_weather(self, location=None):
        self.clear_widgets()

        print(WeatherRoot.current_weather)
        print(self.current_weather)

        if location is None and self.current_weather is None:
            location = 'New York (US)'

        if location is not None:
            self.current_weather = Factory.CurrentWeather()
            self.current_weather.location = location
        self.add_widget(self.current_weather)

    def show_add_location_form(self):
        self.clear_widgets()
        self.add_widget(AddLocationForm())


class LocationButton(ListItemButton):
    pass


class AddLocationForm(BoxLayout):
    search_input = ObjectProperty()
    search_results = ObjectProperty()

    def search_location(self):
        search_template = 'http://api.openweathermap.org/' \
                          'data/2.5/find?q={}&type=like&APPID=' \
                          '090428d02304be901047796d430986e3'
        search_url = search_template.format(self.search_input.text)
        print(search_url)
        request = UrlRequest(search_url, self.found_location)

    def found_location(self, request, data):
        data = json.loads(data.decode()) if not isinstance(data, dict) else data
        cities = ['{} ({})'.format(d['name'], d['sys']['country'])
                  for d in data['list']]
        # self.search_results.item_strings = cities
        self.search_results.adapter.data.clear()
        self.search_results.adapter.data.extend(cities)
        self.search_results._trigger_reset_populate()


class WeatherApp(App):
    pass


WeatherApp().run()