【问题标题】:Why this class variable is None even though it has been initialized?为什么这个类变量是 None 即使它已经初始化?
【发布时间】:2017-01-28 20:05:57
【问题描述】:

我正在学习 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_weather,据我所知这是一个类变量,被定义为ObjectProperty,因为我没有覆盖这个变量的实例变量(我想是的),当我提到self.current_weather 时,我指的是类变量,所以我认为self.current_weatherWeatherRoot.current_weather 相同,但不是因为当我打印这些变量时,我希望两者都是ObjectProperty例如,我得到了:

<ObjectProperty name=current_weather>
None

我的意思是这个变量永远不会是None,因为它是一个类变量所以它总是一个ObjectProperty,但似乎有可能是None,我不明白为什么。

这是此应用程序的 GUI:

这是我的 Kivy 文件:

WeatherRoot:
<WeatherRoot>:
    AddLocationForm

<LocationButton>:
    on_press: app.root.show_current_weather(self.text)

<AddLocationForm>:
    orientation: 'vertical'
    search_input: search_box
    search_results: search_results_list
    BoxLayout:
        height: '40dp'
        size_hint_y: None
        TextInput:
            id: search_box
            size_hint_x: 50
            focus: True
            multiline: False
            on_text_validate: root.search_location()
        Button:
            text: 'Search'
            size_hint_x: 25
            on_press: root.search_location()
        Button:
            text: 'Current Search'
            size_hint_x: 25
    ListView:
        id: search_results_list
        adapter:
            ListAdapter(data=[], cls=main.LocationButton)
    Button:
        height: '40dp'
        size_hint_y: None
        text: 'Cancel'
        on_press: app.root.show_current_weather(None)

所以,当我按下取消按钮并且之前没有搜索过任何位置时,默认值是硬编码的,因为它可以看到'New York (US)。当我之前搜索过某个位置并按下取消按钮时,会显示此位置。

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

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

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()

【问题讨论】:

    标签: python kivy


    【解决方案1】:

    属性为descriptors。虽然是在类级别定义的,但它们具有实例级别的行为,并且大致上会表现得像一个实例变量。

    【讨论】:

    • 当你说属性是描述符时,你是说 Kivy 属性被定义为描述符?或者您的意思是它们是 Python 属性,即可以像属性一样访问的方法?
    • Kivy 属性是描述符,因为它们实现了链接文档中的描述符协议。它们的行为方式类似于普通的 Python 属性,但它们的实现不同(并且它们包括额外的行为)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-12-21
    • 2021-06-21
    • 2012-01-16
    • 2021-11-18
    相关资源
    最近更新 更多