[英]Why this class variable is None even though it has been initialized?
我正在学习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_weather
与WeatherRoot.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()
属性是描述符 。 尽管它们是在类级别定义的,但它们具有实例级别的行为,并且首先近似地将表现为实例变量。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.