del方法
- 调用:
创建对象时,python解释器会默认调用__init__方法,当删除一个对象时,
python解释器也会调用一个方法,这个方法是: __del__()
- 案例:
class Animal:
# 对象初始化时调用
def __init__(self,name):
self.name = name
print(self.name+"来了")
# 对象被回收时调用
def __del__(self):
print(self.name+"被妖怪抓走了")
# 创建对象,初始化 init方法调用
an = Animal("唐僧")
# 手动删除对象,之后将不能在被使用,如果使用会报错
# del an
print(an.name)
# 如果没有手动删除,对象将在使用完才被系统收走
-
案例:
# 创建对象,初始化 init方法调用 an = Animal("唐僧") # 手动删除对象,之后将不能在被使用,如果使用会报错 an1 = an an2 = an print(id(an)) print(id(an1)) print(id(an2)) print("马上删除对象an") del an print("马上删除对象an1") del an1 print("马上删除对象an2") # 这句代码执行完毕,对象才会被真正删除(引用计数) del an2
- 引用计数:
刚创建出来的时候为2,增加一个引用,引用计数+1, del 对象 ,可以减少引用计数,当引用计 数为1时,在del 对象,才会真正被回收
单继承
-
继承概念
用来描述类与类之间的一种关系: 父类、超类、基类 子类、派生类
-
继承的语法
class 子类(父类名,...): 方法... 如果一个类没有明确指明父类,则它的父类为object
-
案例:
- 定义Cat类,包含属性: name,color,age;方法:eat() sleep() catchmouse() - 定义Dog类,包含属性: nage,color,age;方法:eat() sleep() lookafterHouse() - 发现许多重复的东西,优化,抽离一个父类Animal出来
-
总结:
- 子类可以继承父类中所有的属性跟方法(私有除外) - 私有属性不能通过对象直接访问,但可以通过方法访问 - 私有方法,不能通过对象直接访问
-
属性自动化赋值(高级用法)(setattr,getattr,hasattr,isinstance函数的使用)
# 属性自动化赋值 class Dog(): def __init__(self,name,age,gender,color,breed): print(locals()) # pass self.attributeFromdict(locals()) # 自定义方法,设置属性 def attributeFromdict(self,d): self = d.pop('self') for n, v in d.items(): # 内置函数,为self的属性赋值value setattr(self,n,v) def showinfo(self): print(self.name) print(self.age) print(self.breed) print(self.gender) dog =Dog('aa',12,'男','red','京巴') dog.showinfo()
多继承
-
概念
所谓多继承,就是一个类同时有多个父类 思考:狼狗的父类 狼、狗
-
语法
class 子类(父类1,父类2): 方法... 如果父类1,父类2中都有属性,则以先继承的类为标准,如果两个父类存在同名方法,则一样 以先继承的类为准,所有父类中的非同名方法都能被继承到
-
案例
class AAA(): def methodAAA(self): print("a的方法a") class BBB(): def methodBBB(self): print("b的方法b") class CCC(AAA,BBB): def methodCCC(self): self.methodAAA() self.methodBBB() print("c的方法c") ccc = CCC() ccc.methodCCC() # 执行结果 # a的方法a # b的方法b # c的方法c
两个父类中的方法,属性,都会被子类继承
思考: 如果父类中有同名方法,会怎么样?class AAA(): def methodAAA(self): print("a的方法a") # 新增方法,BBB类中有同名方法 def methodBBB(self): print("a的方法b") class BBB(): def methodBBB(self): print("b的方法b") class CCC(AAA,BBB): def methodCCC(self): self.methodAAA() self.methodBBB() print("c的方法c") ccc = CCC() ccc.methodCCC() # 执行结果 # a的方法a # a的方法b # c的方法c
重写父类的方法与调用父类的方法
-
方法重写概念:
所谓重写,就是在子类中,有一个和父类相同名字的方法,子类中的方法会覆盖掉父类中的同名方法
-
方法重写案例:
class SuperClass(): def __init__(self): print("父类的初始化方法") def test(self): print("父类的测试方法") class SubClass(SuperClass): def __init__(self): print("子类的初始化方法") def test(self): print("子类的测试方法") sub = SubClass() # 这里的test方法,调用的为子类中重写的方法 sub.test() # 执行结果 # 子类的初始化方法 # 子类的测试方法
-
调用父类方法:
class SuperClass():
def __init__(self,name):
self.name = name
def test(self):
print("父类的测试方法")
class SubClass(SuperClass):
def __init__(self,name,age):
# SuperClass.__init__(self,name)
# super(SubClass, self).__init__(name)
super().__init__(name)
self.age = age
# 子类重写父类方法
def test(self):
print("子类的测试方法")
print('name:'+self.name+",age:"+str(self.age))
sub = SubClass('aa',12)
sub.test()
# 执行结果
# 子类的测试方法
# name:aa,age:12
多态
-
概念
- 定义时的类型跟运行时的类型不一样,此时就成为多态
严格意义上来讲,python中的多态不叫真正的多态,称之为鸭子类型更合适 - 鸭子类型
“鸭子类型”的语言是这么推断的:一只鸟走起来像鸭子、游起泳来像鸭子、叫起来也像鸭子, 那它就可以被当做鸭子。也就是说,它不关注对象的类型,而是关注对象具有的行为(方法)。
- 鸭子类型弊端
“鸭子类型”语言的程序可能会在运行时因为不具备某种特定的方法而抛出异常:
案例1: 如果一只小狗(对象)想加入合唱团(以对象会不会嘎嘎嘎叫的方法为检验标准), 也学鸭子那么嘎嘎嘎叫,好吧,它加入了,可是加入之后,却不会像鸭子那样走路, 那么,迟早要出问题的。
案例2: 一只小老鼠被猫盯上了,情急之下,它学了狗叫,猫撤了之后,小老鼠的妈妈不无感叹的 对它说:看吧,我让你学的这门儿外语多么重要啊。这虽然是个段子,但是,由于猫在 思考时,使用了 "鸭子测试",它以为会叫的就是狗,会对自己产生威胁,所以撤退了, 也正是因为这个错误的判断,它误失了一次进食机会。
- 定义时的类型跟运行时的类型不一样,此时就成为多态
-
用法
class F1(object):
def show(self):
print("F1.show")
class S1(F1):
def show(self):
print("S1.show")
class S2(S1):
def show(self):
print("S2.show")
def func(obj):
obj.show()
obj1 = F1()
func(obj1)
obj1 = S1()
func(obj1)
obj1 = S2()
func(obj1)
类属性、实例属性
- 类属性
属于类对象所拥有的属性,它被所有类对象的实例对象所公有,在内存中只有一份
-
类属性的访问方式
- 在类外可以通过类名访问
类名.属性名
- 在类外可以通过实例对象访问
对象名.属性名
-
案例:
class Student:
# 类属性
schoolName="西三旗校区"
def __init__(self,name,age):
# 实例属性
self.name = name
self.age = age
st1 = Student('陈独秀',29)
# 通过类名访问类属性
print(Student.schoolName)
# 通过对象访问类属性
print(st1.schoolName)
# 通过对象访问修改属性,会新增对象属性,之后通过对象访问类属性将无法访问到,因为会被新增的对象属性屏蔽
st1.schoolName = '京南校区'
# 类属性访问结果不变
print(Student.schoolName)
# 这只能访问到对象属性
print(st1.schoolName)
# 可以手动删除新增的对象属性
del st1.schoolName
# 因为对象属性被删除,所以,这访问的依旧是类属性
print(st1.schoolName)
静态方法和类方法
-
类方法
- 概念
是类对象所拥有的方法,需要用@classmethod来表示,类方法第一个参数必须为类对象 一般使用'cls', 类方法能够通过类名和对象进行访问
- 用法:
class Student: # 类属性 schoolName="西三旗校区" def __init__(self,name,age): # 实例属性 self.name = name self.age = age # 类方法 (可以直接访问类属性) @classmethod def getSchoolName(cls): return cls.schoolName @classmethod def setSchoolName(cls,newSchoolName): cls.schoolName = newSchoolName st2 = Student('李大钊',30) Student.schoolName = '北平学校' # 通过对象访问类方法 print(st2.getSchoolName()) # 通过类名方法类方法(使用较多) print(Student.getSchoolName()) Student.setSchoolName('同济学校') print(Student.getSchoolName()) 注意: 类方法中可以直接修改当前类的类属性
-
静态方法
- 概念
需要使用@staticmethod进行修饰,静态方法不需要定义参数
- 用法
可以访问类属性,但是必须通过类名, 调用方式:可以通过类名,对象进行调用 class Student: # 类属性 schoolName="西三旗校区" def __init__(self,name,age): # 实例属性 self.name = name self.age = age # 静态方法 (可以通过类名访问类属性) @staticmethod def getSchoolName(): return Student.schoolName
简单总结对比:
- 成员属性、类属性、私有属性
- 成员方法、类方法、静态方法、私有方法
网友评论