1.析构方法
当一个对象被删除或销毁时,解释器会默认调用一个方法为__del__()方法,也称为析构方法。
程序执行结束会自动调用析构方法。
也可以主动运行析构方法:del(实例对象)
2.继承
在编写类时,如果一个类是既有的一个类的特殊版本,则可以使用继承,当一个类继承另一个类时,将自动获得后者的属性和方法。原有的类为父类也叫超类,新类为子类,子类还可定义自己特殊的属性和方法。
在既有的类的基础上编写新类,通常要调用父类的init方法,这将初始化父类的属性,从而让子类也可以使用这些属性。
在创建子类时,必须与父类在同一文件中,且父类位于子类的前面。语法为在定义子类时,在括号内指定父类的名称。
super()是一个特殊的函数,可以调用父类的方法。
class people(object):
def __init__(self,name,age):
self.name=name
self.age=age
#print("start")
def __del__(self):
print('end....')
class students(people):
def __init__(self,name,age,pro):
super().__init__(name,age)
self.pro=pro
student=students('wang',19,'tumu')
print(student.age)
print(student.pro)
在students类调用init方法时,首先用super方法调用了父类的init方法,初始化了name和age,接着又初始化了pro,(因为self是解释器自动传参,所以不用主动传递)
student2=people()
那么student2这个对象就不会有pro这个属性
python也可以继承多个父类,括号中用逗号隔开。
继承也具有传递性。
但是当多个父类中存在相同方法的时候,该调用哪一个呢?是按照广度优先搜索的顺序来的!既先查找自己是否定义了此方法,若没有再找第一个继承的类,若还没有则去找第二个继承的类而不会找第一个继承的类的继承的类,依此类推。
(__mro__可以显示类的依次继承关系)
3.重写父类方法
若父类中一些方法不能满足子类需要时,可以对父类方法进行重写。所谓重写就是在子类中有一个和父类相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法。(魔法方法像init等方法重名了一样被重写)
4.类属性和实例属性
类属性是所有实例都可以使用的,而实例属性是特点的实例对象才可以使用。
所有实例都指向同一个类属性的地址,而实例属性不同,每一个实例属性在内存的不同位置。
类属性是可以在实例中修改的。
class people(object):
pro='haha'
def __init__(self,name):
self.name=name
def fun(self):
print(f"is me {self.name}")
xh=people('zhang')
xl=people('li')
xh.pro='hh'
print(xh.pro)
print(xl.pro)
5.类方法和静态方法
类方法是指类对象所拥有的方法,需要用装饰器@classmethod来标识,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数,类方法可以通过类对象,实例对象调用。
类方法既可以通过类对象,也可以通过实例对象访问。
class people(object):
pro='haha'
def __init__(self,name):
self.name=name
@classmethod
def fun(cls):
print(cls.pro)
xl=people('li')
xl.fun()
people.fun()
类对象所拥有的方法,用@staticmethod来表示静态方法,静态方法不需要任何参数。
静态方法也可以通过类对象和实例对象去访问。
class people(object):
pro='haha'
def __init__(self,name):
self.name=name
@staticmethod
def fun2():
return people.pro
person=people('li')
print(person.fun2())
print(people.fun2())
为什么要使用静态方法?静态方法主要用来存放逻辑性代码,本身和类以及实例对象没有交互,不会涉及到方法和属性的操作。让内存得到充分利用,不需要再声明对象了。