是kivy中一个简单应用程序的以下代码:
from kivy.config import Config
Config.set('kivy', 'keyboard_mode', 'system')
from kivy.app import App
from kivy.uix.boxlayout import BoxLayout
from kivy.lang import Builder
from kivy.properties import StringProperty
Builder.load_file('design2.kv')
class MyWidget(BoxLayout):
def __init__(self):
super(MyWidget, self).__init__()
self.showtext() #Llamamos al método desde el constructor
def showtext(self):
with open("Prueba.txt","r") as f:
self.ids['Label1'].text = f.read()
class myApp(App):
def build(self):
return MyWidget()
def on_pause(self):
return True
def on_resume(self):
pass
if __name__ in ('__main__', '__android__'):
myApp().run()
让 .kv 文件成为(虽然在这里不相关):
<MyWidget>:
BoxLayout:
Label:
id: Label1
我想知道第一个代码中的以下代码片段:
class MyWidget(BoxLayout):
def __init__(self):
super(MyWidget, self).__init__()
self.showtext() #Llamamos al método desde el constructor
据我了解,def __init__(self):
它是一个构造函数。构造函数是干什么用的?另一个问题是关于这条线的: super(MyWidget, self).__init__()
什么是super
?
这个问题并不是 Kivy 所特有的,而是 Python 和一般的 OOP(面向对象编程)范式所特有的。
简短的回答是,虽然该方法
__init__
有时被称为“构造函数”,但它实际上只是一个实例初始化器,它通常用于初始化我们创建的对象的属性,并在类实例化后立即自动执行。在您的情况下,由于我们在其中调用方法,因此showtext
当我们的应用程序启动时,文本已经加载到标签中。super
在这种情况下用于调用父类的初始化程序BoxLayout
。在这种情况下,它等价于BoxLayout.__init__(self, *args, **kwargs)
。长答案如下,所有这些都是针对 Python 3 的,尽管它都适用于Python 2新型
object
类(明确派生自):严格来说,Python 中的“构造函数”一词可能有些含糊。当我们创建一个对象时,涉及到两个特殊的方法,第一个被调用的是方法
__new__
,然后是方法被调用__init__
:__new__
: 基本上它所做的是返回一个有效的类实例。它只构造它的类的一个对象并返回它,所以这应该被认为是类的真正“构造器”。接收对类的引用作为第一个参数 (cls
)。覆盖这个方法并不像在 的情况下那么常见
__init__
,一般来说,它的用途是自定义类的实例化,例如它是创建单例的方法之一:如果我们重写该方法,我们必须通过调用
__new__
父方法(它来自object
所有新式类派生的类)来获取新实例,例如:__init__
:如果它__new__
返回其类的实例(通常),那么__init__
它将新创建的实例作为第一个参数(按照约定)传递给它的方法将self
被隐式执行。如果__new__
它不返回该类的实例,则不会调用它并且必须显式完成。它的一些特点是:在许多语言中,这两种方法都合并为一个,并被视为构造函数。
__init__
您可以在那里找到关于它的辩证斗争,即使它并不完全正确,也有调用构造函数的重要趋势。的基本目标
__init__
是初始化我们创建的对象的属性:在
__init__
这种情况下,创建并初始化radio
每个对象的实例属性、属性,Círculo
并将其与其他圈子区分开来。__init__
我们可以在您可能已经注意到的任何方法之外或任何方法之外创建属性,这就是pi
上面示例中的情况。这两种情况有很大的不同,属性pi
是属于类的属性,由我们创建的类的所有实例共享。radio
相反,它是由__init__
实例创建的,它完全属于对象,通过赋予它不同的属性来初始化它。有关更多信息,以下问题可能会有所帮助:实例属性和类属性之间的区别
现在要完成这一点,请讨论
super
类初始化程序中常用的内容,如您展示的示例中所示。这是因为定义我们自己的初始化程序会覆盖__init__
父类的初始化程序。为了让我们的类继承在其初始化程序中实现的父类的所有特性(我们已经重写了它),因此有必要显式调用它。这正是它所关心的super(MyWidget, self).__init__()
。通常,它允许显式引用父类,因此它允许您将方法调用委托给父类(或多个类)。
离开:
在多重继承的情况下,这是它
super
具有真正潜力的地方,因为它将按特定顺序(方法解析顺序)在父类中查找方法,但这离问题还有很长的路要走。