类中的初始化函数的定义
class Animal(object):
def __init__(self, name, age):
self.name = name
self.age = age
这是一个最简单的类,它的具体含义是:定义一个名为Animal的类,并进行初始化。其中,函数 __init__()是用于将这个类的实例(instance)进行初始化的用途。
那么什么是初始化呢。简单的来说,由于类是一种将各式各样的具体操作进行抽象化的表达,在调用到这个类的一些功能的时候,需要首先创建一个具象的对象——即实例,然后才能让这个实例调用类的一些功能。这里,赋予这个类一些特定的功能,使得它的实例能够在稍后随意的调用,就是初始化的含义。下面是一段伪代码,可以直观地体会到初始化函数的具体作用。
定义 初始化函数(对象自身(某个实例), 参数1, 参数2, ......):
实例的特性1 = 参数1
实例的特性2 = 参数2
注意这里的等号意思是将参数赋值给实例的特性(method),这样做之后,我们就能够通过直接调用的方式来访问特定的参数。
class Animal(object):
def __init__(self, name, age):
self.name = name
self.age = age
# 定义一个函数description,用于打印出实例的两个特性
def description(self):
print(self.name)
print(self.age)
# 创建两个实例dog,cat,并对他们进行初始化
dog = Animal("Sam", 11)
cat = Animal("Lily", 6)
# 调用description函数,打印出绑定到实例上的特性
# 注意这里description函数后不必填入参数,因为它默认传入实例本身
dog.description()
cat.description()
# 打印的结果为
# Sam
# 11
# Lily
# 6
了解了类中的__init__函数的具体作用之后,就可以做一些更加进阶的操作了
类中的变量类型
在类中有两种变量作用域,一种叫做类变量(Class Variable / Member Variable),另一种叫做实例变量(Instance Variable)。类变量指的是这个类下的所有实例所共有的特性,而实例变量则指的是每个实例各自独有的特性。可以这么理解:类变量作用域相对于实例变量来说要稍微广一点(并非如此,仅作为辅助理解用)。
这里还是以上面的例子来说明。
class Animal(object):
is_alive = True# 注意这个类变量
def __init__(self, name, age):
self.name = name
self.age = age
dog = Animal("Sam", 11)
dog.name# "Sam"
dog.age# 11
dog.is_alive# True
由于类变量在初始化之前就已经确定,所以不需要传入。不管我们创建多少个实例,当调用实例的is_alive方法时,始终能够返回True。
当然,也可以针对某个实例修改这个变量is_alive,但这样做只是修改当前这个实例的is_alive的值,并不会影响到其他实例。效果如下所示。
dog.is_alive = False
dog.is_alive# 返回False
cat.is_alive# 返回True
而对于实例变量来说,很显而易见的,实例dog的name 和age方法所绑定的属性与cat中的这些属性互不干扰。
需要注意的是,实例将优先查找是否有满足条件的实例变量存在,假如没有,再使用类变量。这是因为我们可以通过以下操作额外的绑定新的属性上去:
dog.health = True
这样就让dog这个实例多了一个新的属性 health。假如原本已经在类中有定义了一个health的类变量,那么dog实例将忽略类变量health而直接使用绑定上去的实例变量。这也是为什么类变量能被后期覆盖的本质。
类中的继承以及super()调用超类函数
继承,简单的理解就像父子关系。爸爸生了个儿子,那么这个儿子就必定在长相和性格上对爸爸有所继承。同理,定义一个新的类,可以选择继承一个已有的类,通过继承能使这个子类直接获得其父类的所有属性。
直接上例子。
class Animal(object):
def __init__(self, name, age):
self.name = name
self.age = age
class Bird(Animal):# 要继承父类,需要在括号中填入父类的名称,这就是个认爹的操作
pass
crow = Bird("Steve", 4)
crow.name# 返回"Steve"
crow.age# 返回 4
可以看出,这里我定义的Bird类中,并没有给任何的属性,但是由于它是Animal的子类,因此Bird就自动拥有了Animal的所有属性,可以进行直接调用。
进行继承的好处就在于灵活且方便,对于相同的属性,可以不必再写一遍同样的东西,而假如对于某些属性需要进行单独的修改时,也能够通过重新定义的方式进行覆盖。
但有时在一个子类中,既需要使用子类独有的属性,又需要调用到父类的一些属性。这就是super()发挥其强大作用的时候了。
class Animal(object):
def __init__(self, name):
self.name = name
def animal_run(self):
print("%s is running..." % self.name)
class Bird(Animal):
def bird_flying(self):
super(Bird, self).animal_running()# 使用super()调用父类属性
print("%s is flying..." % self.name)
crow = Bird("Alex")
crow.bird_flying()
# 将打印如下内容
# Alex is running...
# Alex is flying...
下面是一段伪代码,用来辅助理解super的用法。
调用超类(子类名称,实例自身).调用的父类属性名称(接收的参数)
References
1. [类和实例 - 廖雪峰Python教程]
http://suo.im/53BXVh
2. [你不知道的super]
https://funhacks.net/explore-python/Class/super.html
领取专属 10元无门槛券
私享最新 技术干货