今天要学习的是面向对象,Python从设计之初就已是一门面向对象的语言,正由于如此,在Python中建立一个类和对象是很容易的,咱们先一块儿来看一下类和对象的定义~html
class 类的名称: 语句块 # 举例说明 class Student: num = 100 def showNum(self): return 200 print(Student.num) # 输出:100 print(Student.showNum) # 输出:<function Student.showNum at 0x009A9468> # Student就是类对象,num是类变量,showNum是方法,self为类对象的实例, 类名称通常须要大写
讲完类和对象,咱们来看一下实例,类是抽象的模板,而实例是根据类建立出来的一个个具体的“对象”,每一个对象都拥有相同的方法,但各自的属性可能不一样;python
class Student: def prt(self): print(self) print(self.__class__) s = Student() s.prt() # 执行结果: # <__main__.Student object at 0x0000000001D7CDA0> # <class '__main__.Student'>
上述例子中self
表明的是类的实例,而self.__class__
指向类,且self 不是 python 关键字,咱们把self换成其它的单词也能够正常运行;设计模式
咱们知道了什么是实例,那实例化又是什么呢,接着看下面这个例子,在Student类中有两个方法,一个是初始化方法__init__
,另外一个是我本身定义的方法showClass()方法数据结构
class Student: num = 100 def __init__(self): self.name = '张三' def show(self): return '李四' print(Student.num) # 输出:100 print(Student.show) 输出:<function Student.show at 0x0000000002765BF8> stu = Student() # 这就是实例化,且实例化会自定调用__init__方法,self会自动传递,不能有return返回值 print(stu.name) # 张三
__init__()
方法,能够用它来为每一个实例定制本身的特征(属性);init()
方法被称为类的构造函数或初始化方法,须要注意的是__init__()
方法不能有return返回值;而后咱们来说一下什么是类变量和实例变量,看看这二者之间有什么不一样;函数
# 实例变量是实例特有的,类变量是类和实例共有的 class Student: num = 100 def __init__(self, name): self.name = name def showClass(self): return 200 print(Student.num) print(Student.showClass) stu = Student('张三') # 实例化,会调用__init__方法,self会自动传递,不能有return返回值 print(stu.name) # 实例变量 print(stu.num) # 类变量
直接看这个实例可能还不太直观,你们本身在程序里面动手运行一下,使用Student类调用num和name两个变量,就会发如今调用num的时候能正常输出,而调用name的时候报错了。而后再用实例对象stu调用这两个变量试试,咱们就能得出下面两个结论:性能
讲完了类变量和实例变量,那咱们来看一下类方法和实例方法:学习
class Student: num = 100 def __init__(self, name): self.name = name def showClass(self): return '张三' @classmethod def add(cls): print(cls) stu = Student('张三') # 实例化,会调用__init__方法,self会自动传递,不能有return返回值 print(stu.name) # 实例变量 输出:张三 print(stu.num) # 类变量 输出: 100 print(stu.__dict__) # 类的属性保存在本身的字典中,包括类变量和方法 print(stu.__dict__) # 实例的属性保存在本身的字典中,包括实例的变量 stu.add() # 类方法能够被实例对象调用 输出:<class '__main__.Student'> stu.__class__.add() print(Student.showClass()) # 报错,实例方法不能够被类对象调用 print(Student.name) # 实例能够访问类的属性,类没法访问实例的属性
咱们动手试一下,分别用Student类,和实例对象stu来调用类方法和实例方法,咱们就能得出一下结论:测试
除了类方法和实例方法以外,还有一个方法叫作静态方法,咱们一块儿来看一下静态方法如何使用:编码
class Student: def __init__(self, name): self.name = name @staticmethod def sub(): print('static') stu = Student('李四') stu.sub() # 实例能够调用静态方法 输出:static Student.sub() # 类能够调用静态方法 输出:static
而后咱们能够得出一下两个结论:设计
__
开头的属性为私有属性,不能在类的外部被使用或直接访问;_
开头的为保护属性,只有类实例和子类实例能访问,需经过类提供的接口进行访问;咱们来看一下私有属性和保护属性是如何使用的:
class Student(object): def __init__(self): self.__private_field = 200 # private self._protect_field = 200 # protect stu = Student() # print(stu.__private_field) # 报错,实例对象不能够调用私有属性 print(stu._protect_field) # 输出:200
class Student: num = 100 def __init__(self, name): self.__name = name @property def name(self): return self.__name @name.setter def name(self, name): self.__name = name @name.deleter def name(self): del self.__name stu = Student('张三') print(stu.name) # 输出:张三 stu.name = '李四' print(stu.name) # 输出:李四
class Student: def __init__(self, name): self.__name = name def get_name(self): return self.__name def set_name(self, value): self.__name = value def del_name(self): del self.__name print('实例的属性被删除了') # 这里表示property是用来修饰name这个属性的 name = property(fget=get_name, fset=set_name, fdel=del_name, doc='hello') stu = Student('张三') print(stu.name) # 张三 stu.name = '李四' # 给name赋值 print(stu.name) # 李四
class Animal: def __init__(self): self.type = 'animals' def eat(self): print('{} 吃,Animal类中'.format(self.__class__.__name__)) # Animal 吃,Animal类中 class Person(Animal): def talk(self): print('讲话') # animal = Animal() # animal.eat() # # print(animal.type) # animals # animal.talk() # 报错,父类不能够调用子类的方法 person = Person() print(person.type) # animals # Person调用Animal类的eat方法 person.eat() # 输出:Person 吃,Animal类中 person.talk() # 讲话
class Animal: __name = 'animal' def __init__(self): self.type = 'animal' def eat(self): print('{} eat'.format(self.__class__.__name__)) class Person(Animal): def talk(self): print('talk') person = Person() print(person.__name) # 子类不能访问 父类的私有属性
__dict__
中查找->而后从对象所在类的__dict__
中查找->而后从父类的__dict__
中查找,直至找到或者报错没有找到;class Animal: def __init__(self): self.type = 'animal' def eat(self): print('{} eat'.format(self.__class__.__name__)) class Person(Animal): def eat(self): print('洗手') # 洗手 print('{} eat'.format(self.__class__.__name__)) # Person eat super().eat() # 调用父类的方法 # Person eat # super(Person, self).eat() 等价于 super().eat() person = Person() person.eat()
class Animal: def __init__(self): self.one = 'one' class Person(Animal): def __init__(self): self.two = 'two' self.three = 'three' def show(self): print(self.one, self.two, self.three) person = Person() print(person.__dict__) # 输出:{'two': 'two', 'three': 'three'} person.show() # 报错,person没有one这个属性 print(person.one) #一样报错
class Animal: def __init__(self): self.one = 'one' class Person(Animal): def __init__(self): self.two = 'two' self.three = 'three' super().__init__() # 继承父类的__init__方法,且父类init方法的调用写在子类的什么地方也有讲究 def show(self): print(self.one, self.two, self.three) person = Person() print(person.__dict__) print(person.one) # 输出:one ,由于继承了父类的init__方法,因此能够访问one属性
super()
函数是用于调用父类(超类)的一个方法, Python 3 可使用直接使用super().xxx 代替 super(Class, self).xxx
;__init__
方法,由于Mixin类不作为独立类使用;