python kivy ‘NoneType‘ object has no attribute ‘xxx‘ 问题解决方案

有很多中情况都是我遇到的,现在写出来:

一、未实例化而使用

# py文件
class A(BoxLayout)
	a = ObjectProperty(None)

	def __init__(self)
		a.text = 'textname'
#kv文件
<A>:
	a:alabel
	Label:
		id:alabel
		text:"x"

此文件报错

AttributeError: 'NoneType' object has no attribute 'text'
# 属性错误:“NoneType(无类型)”对象没有'text'属性

原因是__init__()对a属性的操作,虽然你在kv文件中定义了a是个Label控件,但__init__()是在类实例化完成前进行的工作,在实例化完成之前,a还只是个ObjectProperty(None),是NoneType型的属性而已,他没有Label的意义自然不能被引用为Label。

目前我看到的两个解决方案方法都不太好,不知道有没有这种在实例化之后再自动执行的函数,inti call get del 都不成
1、加载时间跳帧函数,让这句调用在实例化执行。
2、在实例化之后直接再调用一个自定义的set函数来设定。
如下(kv代码如上):

class A:
	a = ObjectProperty(None)
	def set()
		self.a.text= 'textname'

#类内调用方法1:	
	def oter()
	Clock.schedule_once(self.set)
	"""schedule_once不带第二个时间参数时表示在下一帧加载"""
	
#类外调用方法2:	
a = A()
a.set()	

二、kv文件问题而不加载

如果出现如下kv代码 一般不会报错,但也很可能不会加载,也就会导致你的类的控件规则定义无效。

#kv文件
A:
# A:是引用A作为类使用的代码,而不是定义A的,
# 应为:"<A>:",
# 更有甚的时候用来定义A的语句写成<B>:这也是不行的哦!
	a:alabel

	label:
	# 一般来说kivy对kv文件中系统元定义的控件类都有大小写容错
	# 也就是你在此处写label是没有问题的,
	# 但是有些用户自定义的类就没有这个待遇了
	# 你必须要写大写,最好是类的定义就是大写开头的。
		id:alabel
		text:""
		#通常意义上说,label控件在没有text的时候不能称之为控件	

三、全局变量的问题

# kv文件同一
# py文件

class A(BoxLayout)
	a = ObjectProperty(None)

TEXT =A()

# 其它位置调用
cc = TEXT.a.text
# 这个也是报错的,同样的错误。

一些老手应该不会犯这样的错误,但我犯了。全局变量TEXT只是定义为了一个A类的变量,并没有进行实例化,你引用的只是一个表明我是一个A类的变量,这样自然无法加载其属性规则。
你如果必须用到这个全局变量的话就如下操作

在第一次应用或系统加载时使用如下语句

# kv文件同一
# py文件

class A(BoxLayout)
	a = ObjectProperty(None)
		
TEXT =A()

# 其它位置调用
global TEXT
aa=A()
TEXT = aa
cc = TEXT.a.text
# 这样就不犯错了,以后也能按照全局变量来引用TEXT了

版权声明:本文为modytansa原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。