要跑师兄的代码,已经毕业,把python面向对象复习一遍,好理解师兄代码。
主要摘自廖大神的教程,方便自己复习要点
Python类的基本概念
如何定义类
仍以Student类为例,在Python中,定义类是通过class
关键字:
class Student(object):
pass
class
后面紧接着是类名,即Student
,类名通常是大写开头的单词,紧接着是(object)
,表示该类是从哪个类继承下来的,继承的概念我们后面再讲,通常,如果没有合适的继承类,就使用object
类,这是所有类最终都会继承的类
类的成员变量
python可以随意给一个对象绑定属性,对于我们一定要绑定的,可以在构造函数里绑定,看下面的构造函数
类的构造方法
模式:__init__(self,...)
,注意第一个参数是self
,调用的时候当它不存在。
class Student(object):
def __init__(self, name, score):
self.name = name # 绑定成员变量了
self.score = score
类的成员函数
与构造方法有类似特点,就是第一个参数是self
,调用的时候当它不存在。
class Student(object):
def print_score(self):
print('%s: %s' % (self.name, self.score))
访问控制
变量以双下划线开头__
,例如以下代码将name
和score
属性变成私有成员变量
class Student(object):
def __init__(self, name, score):
self.__name = name
self.__score = score
def print_score(self):
print('%s: %s' % (self.__name, self.__score))
类的继承
继承可以让子类拥有父类的一切属性、方法,子类还可以覆盖父类的方法
class Animal(object): # 基类
def run(self):
print('Animal is running...')
def swim(self):
print('Animal is swimming...')
class Dog(Animal): # Dog类拥有了run方法
def swim(self): # Dog 重载了swim方法
print('Dog can swimming well...')
-
使用
isinstance(a,Dog)
可以判断对象a是不是Dog类型的,如果是的话,那它也肯定是其父类Animal
类型的。 -
如果要多重继承,可以在类定义的括号里面放入多个类来实现。
class Dog(Anminal, suckler)
类的多态
python多态不像c++要整虚函数才能多态,python只要这个对象有这个方法,就是多态。也不用管传入的啥类型的,当然我们自己定义函数可以做一下类型判断,防止传入非法参数
def swim_twice(animal):
animal.swim()
animal.swim()
swim_twice(Animal()) # Animal is swimming...
swim_twice(Dog()) # Dog can swimming well...
class D(object):
def swim(self):
pass
swim_twice(D()) # 也ok
Python类进阶
获取对象信息
python可以在ide中使用,也可以交互式使用。在交互式使用时,往往无法知道一个类有哪些方法与属性,因此python提供了专门的函数来看这些信息,另外python中函数本身也是一种类型的对象,因此直接显示的时候看不出来哪个是属性哪个是对象。
type(instance)
函数,传入对象,返回对象类型,types
模块内置一些类型,可以结合type
函数来查看是某种内建类型。如types.FunctionType
可以用来判断一个对象是否是函数类型的。isinstance(instance,class)
用来判断某个instance是否是属于某个class或者它的子类。dir(instance)
用来获取一个对象的所有属性以及方法hasattr(instance, str)
判断一个instance是否有str这个属性或者方法。同理还有getattr(instance,str)
、setattr(instance, str)
类的属性与对象属性
类属性与对象属性区别
类似c++类的静态成员,类的属性可以通过class.attr
的方式访问(在类的内部只能这么访问),有具体对象时,也可以通过instance.attr
访问。
class Student(object):
count = 0
def __init__(self, name):
self.name = name
Student.count=Student.count+1 #没创建一个实例,count+1
类属性与对象属性的动态绑定
类的属性与对象属性都可以动态绑定,给类绑定的属性,所有对象都可以访问;给对象绑定的属性,只有
class Student(object):
pass
def func(self,instance):
pass
s = Student()
s.name = 'student1' # 给对象绑定属性
s.func = types.MethodType(func,s) # 给对象绑定方法,麻烦些
Student.name1 = 'student'
Student.func1 = types.MethodType(func,Student)
同样,可以通过__slots__
方法来限制动态绑定,对子类不起效果。
class Student(object):
__slots__=('attr1','attr2') # 限定只能绑定这两个属性
隐藏类的getter、setter方法
python可以通过定义__
开头的变量,然后使用getter和setter方法来进行访问控制。但是还可以用@property
方法来隐藏getter和setter方法,提供对属性类似直接操作的方式,但内部却走了实现的getter和setter方法
class Student(object):
@property
def name(self): #getter 实现逻辑
return self._name
@name.setter
def name(self,value): # setter 实现逻辑
self._name = value
s = Student()
s.name = 'hello' # 将函数名当属性用
print(s.name)
python类经常需要重载的内置方法
__str__(self)
这个方法在print的时候会被调用,如果不重载,直接print我们自定义对象会显示地址信息,可读性较差
__repr(self)__
这个方法在不调用print,直接使用对象本身作为单独的执行语句时显示,常用在交互式python环境中
__iter(self)__
如果希望对象用于for...in
循环的话,需要重载这个函数
__getitem(self,n)__
如果希望实现通过下标取元素、以及切片操作,则要重载这个函数
__getattr(self,attr)__
实现动态返回一个属性值。当用户通过instance.attr
访问实例的某个不存在的属性时,会走这个函数。
__call__(self,args)__
类似c++中重载operator()
,实现对象实例本身当函数用,可以用callable(instance)
方法判断一个对象实例是否可调用