Python3(基础|高级)语法实战(|多线程|多进程|线程池|进程池技术)|多线程安全问题解决方案
一: 类定义语法
通过下面的实例,你将会了解到如下的内容体系:
(1)类静态属性: 定义类时定义的属性
(2)类动态属性: 实例化类后,通过:对象.属性= 属性值 添加的属性
(3)类初始化过程: __init__(self)被执行,相当于java中的构造函数
(4)类变量与实例变量: 类变量所属所有的实例对象;实例对象只属于本实例
(5)怎样限制某个类无限添加动态属性:使用__slots__ 内置的元组限定动态添加的属性
(6)类的成员访问权限: private 与public 两种权限
(7)装饰器:让get|set方法装饰成属性,可以使用:对象.属性或者对象.属性=属性值的方式操作私有属性
(8)Python类的三种注释
# -*- coding:utf8 -*- class ClassCreate: """A simple example class""" # 类的静态属性i i = 1234 @staticmethod def functionMethod(self): return "I Love You !" print( """ 【面向对象OOP编程是一种编程思想: Python中使用关键字class来创建一个类,class之后紧根类名,并与冒号结尾】 """) print("调用类的静态方法:", "使用类名.静态方法(类的实例化对象)") myClass = ClassCreate() print(ClassCreate.functionMethod(myClass)) print() print("类的成员变量为所有对象实例共享:[静态属性] ", myClass.i) print( """ 调用类的内置属性: __name__,__doc__,__module__,__base__,__dict__ """ ) print("打印类的内置属性: ") print(ClassCreate.__class__) print(ClassCreate.__name__) print(ClassCreate.__doc__) print(ClassCreate.__base__) print(ClassCreate.__bases__) dictData = ClassCreate.__dict__ print(dictData) print() print(dictData['functionMethod']) print(""" 类的属性分: (1)定义类时定义的属性叫静态属性 (2)动态属性是通过:类对象.属性名=属性值的方式动态添加的属性成为动态属性 """) class Person: pass person = Person() person.name = "张三" person.age = 30 print(''' 使用一个空类,处理动态添加属性的问题,在实际引用中,所有的类都具有这种动态添加的属性的特性 ''') print("访问类的动态属性: 用户的名称%s" % person.name, "用户的年龄: %d" % person.age) print("删除类的动态属性: name: 使用: ", "del person.name") del person.name try: print("访问类的动态属性: 用户的名称%s" % person.name, "用户的年龄: %d" % person.age) except AttributeError as err: print("访问删除的动态属性name,异常: ", err.__traceback__) print(""" 为了无上限的给类动态添加属性: 可以使用__slots__属性给类可以动态添加属性的限制,__slots__元组可以限制类中添加的属性:例如定义类的时候 限制类只能添加动态属性: __slots__ = ('name','age','address')这些属性,如添加这些以外的属性,将会报错 """) print('例如: 我们定义Record类') # 定义一个空类,设置合法的属性为 class Record: """使用内置属性__slots__声明类的合法动态属性""" __slots__ = ('name', 'age') address = '' # 该类包括一个类属性: address Anna = Record() Anna.name = '张三' # 修改类变量address,只能使用:类名.属性名 = 属性值;而不能使用:对象.属性名=属性值的方式 Record.address = '北京市' Anna.age = 20 print("Anna : ", Record.__dict__) # 访问类变量确可以使用:对象名.属性名 print("长期居住地址: ", Record.address) print(''' 当我们动态前景: college属性时,看看发生声明效果 ''') try: Anna.college = '清华大学' print(Anna.college) except AttributeError as err: print("添加非法的动态属性(college),异常信息: %s......." % err) print() print('-------------------------------------------------------------------------------------------------') print(""" 实例化对象: 通常我们要使用类中的成员及方法完成相应的业务逻辑,需要实例化该类: python中,实例化对象有两种方式: (1)类名+括号: 类名() 当我们没有在类中声明__init__()方法或者时声明了__init(self)__时,实例化类就只需: 类名() 即可 (2)类名+括号(参数列表) 当我们声明了__init__(self,other parameters) ,方式除了有self参数外,还有我们拓展的对象成员变量时,需要使用这种方式创建类实例对象 """) class PersonInstance: """类实例化的方式,重写类的init方法""" # 该方法在类实例化时,首先被调用,主要完成一些初始化功能 def __init__(self, name, age, address): self.name = name self.address = address self.age = age print("name|age|address这上属性属于该类实例化后的对象的成员;这些成员变量属于所有实例对象共有") def getinfo(self): return self.name, str(self.age), self.address person = PersonInstance("老杨", 20, "北京市海淀区中关村软件创新中心101") print("调用类的普通方法,看法该方法返回的值 ", person.getinfo()) print("调用类的普通方法,看法该方法返回的值类型: ", type(person.getinfo())) print() print("隐藏调用类的初始化方法: ") class MyChildren: """演示隐藏调用类的初始化化法""" def __init__(self): print(""" MyChildren类初始化时,init方法会被调用;对于一个没有初始化函数的类,在实例化时, 也会调用内部默认的__init__函数,如果在类中实现了函数__init__,就会优先调用自定义的函数__init__ """) # 类初始化对象 myChildren = MyChildren() print("显示调用: __init__()初始化方法:") print("显示调用的结果: ", MyChildren.__init__) print(""" 注意:如果类中的__init__()函数,有除了self以外的参数。实例化类时,就必须输入与__init__函数 对应的参数,否则就会报错...; 在类的代码块中,可以使用self关键字来指定本身。另外,类中的成员函数必须第一个参数时self,这样才能保证, 使用类实例化的对象能够调用自己的成员函数; """) print('--------------------将成员函数定义在类外面-----------------------------') print(""" 如果将类中的方法看成函数的话,完全可以把方法定义在类的外边,但是函数的第一个参数必须时self这个规则必须保留 """) # 定义在类外面的方法 # 这种方法是的成员函数可以被多个类使用,从而提高了代码的重用性 def handlerFun(self): return "I Love You!....." class MyHandlerFun: """A simple example class.....""" idea = 123456 # 在类的内部指定成员函数 fun = handlerFun # 函数本身就是一个对象,可以赋值给变量 myHandlerFun = MyHandlerFun() print("调用实例化对象的成员函数handlerFun: ", myHandlerFun.fun()) print("调用实例化对象的成员函数handlerFun: ", MyHandlerFun.fun(myHandlerFun)) print('-------------------------------------类内的成员互访------------------------------------') class MyInnerClass: """A Record class""" def __init__(self, name, age): self.name = name self.age = age def getAge(self): return self.age def getName(self): return self.name def getRecord(self): return self.name, self.age print(""" 在类内部可以使用self.属性或者self.方法 ; self代表当前类的实例对象; """) myInnerClass = MyInnerClass("老高", 25) print("MyInnerClass实例化对象信息: ", myInnerClass.__dict__) print(myInnerClass.getRecord()) print("getRecord方法返回值类型:", type(myInnerClass.getRecord())) print() print(""" Python中的访问权有: public(共有的)|private(私有的) 属性访问权限体现为: 在变量前加两个下划线"__",表示私有的,没加默认为公有的访问权限 也就是说Python中默认权限时public,即所有的对象都是可以访问的 """)
二:静态|动态属性演示
D:\program_file_worker\anaconda\python.exe D:\program_file_worker\python_source_work\SSO\grammar\oop\ClassGrammarCreate.py
【面向对象OOP编程是一种编程思想:
Python中使用关键字class来创建一个类,class之后紧根类名,并与冒号结尾】
调用类的静态方法: 使用类名.静态方法(类的实例化对象)
I Love You !类的成员变量为所有对象实例共享:[静态属性] 1234
调用类的内置属性: __name__,__doc__,__module__,__base__,__dict__
打印类的内置属性:
<class 'type'>
ClassCreate
A simple example class
<class 'object'>
(<class 'object'>,)
{'__module__': '__main__', '__doc__': 'A simple example class', 'i': 1234, 'functionMethod': <staticmethod(<function ClassCreate.functionMethod at 0x0000015B35B64D60>)>, '__dict__': <attribute '__dict__' of 'ClassCreate' objects>, '__weakref__': <attribute '__weakref__' of 'ClassCreate' objects>}<staticmethod(<function ClassCreate.functionMethod at 0x0000015B35B64D60>)>
类的属性分:
(1)定义类时定义的属性叫静态属性
(2)动态属性是通过:类对象.属性名=属性值的方式动态添加的属性成为动态属性
使用一个空类,处理动态添加属性的问题,在实际引用中,所有的类都具有这种动态添加的属性的特性访问类的动态属性: 用户的名称张三 用户的年龄: 30
删除类的动态属性: name: 使用: del person.name
访问删除的动态属性name,异常: <traceback object at 0x0000015B35B7CD80>为了无上限的给类动态添加属性: 可以使用__slots__属性给类可以动态添加属性的限制,__slots__元组可以限制类中添加的属性:例如定义类的时候
限制类只能添加动态属性: __slots__ = ('name','age','address')这些属性,如添加这些以外的属性,将会报错例如: 我们定义Record类
Anna : {'__module__': '__main__', '__doc__': '使用内置属性__slots__声明类的合法动态属性', '__slots__': ('name', 'age'), 'address': '北京市', 'age': <member 'age' of 'Record' objects>, 'name': <member 'name' of 'Record' objects>}
长期居住地址: 北京市当我们动态前景: college属性时,看看发生声明效果
添加非法的动态属性(college),异常信息: 'Record' object has no attribute 'college'.......
-------------------------------------------------------------------------------------------------
实例化对象: 通常我们要使用类中的成员及方法完成相应的业务逻辑,需要实例化该类: python中,实例化对象有两种方式:
(1)类名+括号: 类名()
当我们没有在类中声明__init__()方法或者时声明了__init(self)__时,实例化类就只需: 类名() 即可
(2)类名+括号(参数列表)
当我们声明了__init__(self,other parameters) ,方式除了有self参数外,还有我们拓展的对象成员变量时,需要使用这种方式创建类实例对象name|age|address这上属性属于该类实例化后的对象的成员;这些成员变量属于所有实例对象共有
调用类的普通方法,看法该方法返回的值 ('老杨', '20', '北京市海淀区中关村软件创新中心101')
调用类的普通方法,看法该方法返回的值类型: <class 'tuple'>隐藏调用类的初始化方法:
MyChildren类初始化时,init方法会被调用;对于一个没有初始化函数的类,在实例化时,
也会调用内部默认的__init__函数,如果在类中实现了函数__init__,就会优先调用自定义的函数__init__
显示调用: __init__()初始化方法:
显示调用的结果: <function MyChildren.__init__ at 0x0000015B35B65120>注意:如果类中的__init__()函数,有除了self以外的参数。实例化类时,就必须输入与__init__函数
对应的参数,否则就会报错...;
在类的代码块中,可以使用self关键字来指定本身。另外,类中的成员函数必须第一个参数时self,这样才能保证,
使用类实例化的对象能够调用自己的成员函数;--------------------将成员函数定义在类外面-----------------------------
如果将类中的方法看成函数的话,完全可以把方法定义在类的外边,但是函数的第一个参数必须时self这个规则必须保留
调用实例化对象的成员函数handlerFun: I Love You!.....
调用实例化对象的成员函数handlerFun: I Love You!.....
-------------------------------------类内的成员互访------------------------------------在类内部可以使用self.属性或者self.方法 ; self代表当前类的实例对象;
MyInnerClass实例化对象信息: {'name': '老高', 'age': 25}
('老高', 25)
getRecord方法返回值类型: <class 'tuple'>
Python中的访问权有: public(共有的)|private(私有的)
属性访问权限体现为: 在变量前加两个下划线"__",表示私有的,没加默认为公有的访问权限
也就是说Python中默认权限时public,即所有的对象都是可以访问的
Process finished with exit code 0
三:通过get或者set方法获取或者修改私有属性
通常,在类中定义的私有成员,通常需要提供两个方法:
get(self)方法,读取私有属性
set(self ,value)方法, 修改私有属性
另外,我们也可以使用装饰器操作,实现访问私有属性的get方法装饰为公有的属性一样,可以使用:对象.属性 这样的方式访问私有成员;
下面我们来提供: set方法的装饰器,可以通过: 对象.私有属性= 属性值 的方式修改私有变量的值 ;
也即是使用装饰器技术实现类的私有化(@property)
我们知道,私有化技术提供了程序的健壮性,使得一些不愿意暴露的信息细节封装在类中,这些信息不暴露给调用方,这对应一些机密信息得到基本的安全保障
但是,必须提供一个为私有化变量封装的get方法,通过调用get方法对外提供服务
由于私有化属性不能被直接访问,使得类属性的取值方式发生了改变:也即是不能使用:【 实例对象.属性 】的方式进行访问
下面我们通过"装饰器"技术,它可以将get和set方法装饰成类中的一个属性,从而是私有化的类属性也可以直接方法
# -*- coding:utf8 -*- # 继承:inherit class MyClassInheritBaseClass: """A simaple inherit class""" # 职业: 默认科学家,是有变量 __Occupation = "scientist" # 重写__init__(self) def __init__(self, name, age, address, college): self.name = name self.age = age self.address = address self.college = college # 获取类的成员属性 def getMyClassInheritBaseClass(self): return self.name, self.age, self.address, self.college # 提供公共方法方位类中的私有成员属性 def getOccupation(self): return self.__Occupation # 将get函数装饰成属性 @property def Occupation(self): return self.__Occupation def setOccupation(self, value): self.__Occupation = value print() my = MyClassInheritBaseClass('老杨', 30, '北京市朝阳区三里屯大街1001号胡同20小院', '北京大学') # 通过set方法修改私有变量 my.setOccupation("艺术家") print("调用公共方法访问私有属性: ", my.getOccupation()) print("================================================================================================") my1 = MyClassInheritBaseClass('老高', 30, '北京市昌平区001号胡同20小院', '北京大学') print("调用公共方法访问私有属性my1: ", my.getOccupation()) print("==================================my1==============================================================") print("通过访问属性的方式访问私有属性,该私有属性时通过装饰器转换get方法为可以访问的公有属性: %s" % my.Occupation) print() print("类中的属性字典: ", MyClassInheritBaseClass.__dict__) print(""" Python语法会自动私有变量改名字,通过这种方式,让实例化对象找不动私有变量,下面我们直接访问这个名称来验证结果 """) print("私有属性访问: ", my._MyClassInheritBaseClass__Occupation) print(""" 通常,在类中定义的私有成员,通常需要提供两个方法: get(self)方法,读取私有属性 set(self ,value)方法, 修改私有属性 另外,我们也可以使用装饰器操作,实现访问私有属性的get方法装饰为公有的属性一样,可以使用:对象.属性 这样的方式访问私有成员,如上面的: ===================== @property=装饰器============================== @property def Occupation(self): return self.__Occupation ============================================================== """)
输出效果如下:
D:\program_file_worker\anaconda\python.exe D:\program_file_worker\python_source_work\SSO\grammar\oop\ClassGrammarInheritBaseCreateClass.py
调用公共方法访问私有属性: 艺术家
================================================================================================
调用公共方法访问私有属性my1: 艺术家
==================================my1==============================================================
通过访问属性的方式访问私有属性,该私有属性时通过装饰器转换get方法为可以访问的公有属性: 艺术家类中的属性字典: {'__module__': '__main__', '__doc__': 'A simaple inherit class', '_MyClassInheritBaseClass__Occupation': 'scientist', '__init__': <function MyClassInheritBaseClass.__init__ at 0x000002BFB8454F40>, 'getMyClassInheritBaseClass': <function MyClassInheritBaseClass.getMyClassInheritBaseClass at 0x000002BFB8454FE0>, 'getOccupation': <function MyClassInheritBaseClass.getOccupation at 0x000002BFB8455080>, 'Occupation': <property object at 0x000002BFB843D210>, 'setOccupation': <function MyClassInheritBaseClass.setOccupation at 0x000002BFB84551C0>, '__dict__': <attribute '__dict__' of 'MyClassInheritBaseClass' objects>, '__weakref__': <attribute '__weakref__' of 'MyClassInheritBaseClass' objects>}
Python语法会自动私有变量改名字,通过这种方式,让实例化对象找不动私有变量,下面我们直接访问这个名称来验证结果
私有属性访问: 艺术家
通常,在类中定义的私有成员,通常需要提供两个方法:
get(self)方法,读取私有属性
set(self ,value)方法, 修改私有属性
另外,我们也可以使用装饰器操作,实现访问私有属性的get方法装饰为公有的属性一样,可以使用:对象.属性 这样的方式访问私有成员,如上面的:Process finished with exit code 0
-------------------------------------从输出结果----------------------------------------------------------------
我们可以看到,修改类的私有属性时,一个类实例化对象修改,会影响到其它实例化对象的改私有属性的值也会受到影响;这点我们需要特别注意;一处修改多处受到影响; 下面的装饰器可以来修改私有属性时,可以在对应修改属性的方法中添加判断逻辑进行限制,以便满足业务需求;
四: 通过装饰器来获取私有属性或者修改私有属性
通过"装饰器" 来实现类私有化属性的get方法与set方法装饰成类的属性, 被装饰后的私有属性可以与原属性同名,也可以不同同名; 通过装饰器装饰后的set或者get方法后,访问私有属性可以使用: 对象.属性的名称 的方式来访问私有属性; 装饰后的属性与被装饰的方法的名称相同;
print("Python语法中的装饰器:") print() print(""" 下面我们来提供: set方法的装饰器,可以通过: 对象.私有属性= 属性值 的方式修改私有变量的值 ; 也即是使用装饰器技术实现类的私有化(@property) 我们知道,私有化技术提供了程序的健壮性,使得一些不愿意暴露的信息细节封装在类中,这些信息不暴露给调用方,这对应一些机密信息得到基本的安全保障 但是,必须提供一个为私有化变量封装的get方法,通过调用get方法对外提供服务 由于私有化属性不能被直接访问,使得类属性的取值方式发生了改变:也即是不能使用:【 实例对象.属性 】的方式进行访问 下面我们通过"装饰器"技术,它可以将get和set方法装饰成类中的一个属性,从而是私有化的类属性也可以直接方法 """) print() print("------------------------装饰器@property实现私有变量的get函数------------------------------") class ExchangeMeetingClassGet: """使用装饰器(@property)将访问类私有属性的get方法装饰成类的一个属性,使得可以改私有属性可以直接访问""" __Operation = "世界文化交流" __address = '北京市海淀区中关村文化交流中心北苑路北10002路' # 重写类的__init__方法,该方法相当于java中的有参构造函数;该函数会在类实例化时被python内部机制调用 def __init__(self, name, age): self.name = name self.age = age # 定义一个成员函数(获取当参会人员基本信息) def getExchangeMeetingClass(self): return self.name, self.age # 将get方法装饰成属性 @property def Address(self): return self.__address # 实例化对象exchangeMeeting exchangeMeeting = ExchangeMeetingClassGet("张三", 30) # 访问私有属性__Operation|__address # 访问__Operation属性时,会抛出异常: 'ExchangeMeetingClass' object has no attribute '__Operation' try: print("私有属性【__Operation】:", exchangeMeeting.__Operation) except AttributeError as err: print("访问类的私有属性'__Operation'异常,异常信息: ", err) print() print("访问类的私有属性[__address]: ", exchangeMeeting.Address) ''' 访问类的私有属性时【__address】: 我们需要注意: (1)可以使使用实例对象.属性名 的方式访问类的私有属性,但是该属性名称必须与装饰器装饰的方法名保持一致,而不是一私有属性名保持一致 如我们这样访问私有成员会报错: print("访问类的私有属性[__address]: ", exchangeMeeting.__address) ''' print() print("-----------下面我们来探究通过装饰器来使得私有化属性可以被修改-----------------------") class ExchangeMeetingClassSet: """使用装饰器(@property)将访问类私有属性的get方法装饰成类的一个属性,使得可以改私有属性可以直接访问""" __Operation = "世界文化交流" __address = '北京市海淀区中关村文化交流中心北苑路北10002路' # 重写类的__init__方法,该方法相当于java中的有参构造函数;该函数会在类实例化时被python内部机制调用 def __init__(self, name, age): self.name = name self.age = age # 定义一个成员函数(获取当参会人员基本信息) def getExchangeMeetingClass(self): return self.name, self.age # 将get方法装饰成属性 @property def Address(self): return self.__address @property def OperationSetValue(self): return self.__Operation # 将set函数装饰成属性,通过该装饰器,可以使修改私有属性: 实例对象.私有属性 = 属性值 # 该set装饰器必须与上面的get装饰器同时存在,不然程序识别不了该装饰器;而且get与set的方法名必须相同,其实,私有属性__Operation已经被改名为OperationSetValue @OperationSetValue.setter def OperationSetValue(self, value): if (value != "世界文化交流") and (value != "世界艺术交流展会"): raise (ValueError('Operation must be 世界文化交流 or 世界艺术交流展会')) else: self.__Operation = value exchangeMeetingClassSet = ExchangeMeetingClassSet("小张", 50) # 修改私有属性值{__Operation:'世界艺术交流展会'} exchangeMeetingClassSet.OperationSetValue = '世界艺术交流展会' print("实例对象属性集合: ", exchangeMeetingClassSet.__dict__) print("访问类私有属性[__Operation]: ", exchangeMeetingClassSet.OperationSetValue)
五:装饰器装饰set|get方法后,访问私有属性运行效果
Python语法中的装饰器:
下面我们来提供: set方法的装饰器,可以通过: 对象.私有属性= 属性值 的方式修改私有变量的值 ;
也即是使用装饰器技术实现类的私有化(@property)
我们知道,私有化技术提供了程序的健壮性,使得一些不愿意暴露的信息细节封装在类中,这些信息不暴露给调用方,这对应一些机密信息得到基本的安全保障
但是,必须提供一个为私有化变量封装的get方法,通过调用get方法对外提供服务
由于私有化属性不能被直接访问,使得类属性的取值方式发生了改变:也即是不能使用:【 实例对象.属性 】的方式进行访问
下面我们通过"装饰器"技术,它可以将get和set方法装饰成类中的一个属性,从而是私有化的类属性也可以直接方法
------------------------装饰器@property实现私有变量的get函数------------------------------
访问类的私有属性'__Operation'异常,异常信息: 'ExchangeMeetingClassGet' object has no attribute '__Operation'访问类的私有属性[__address]: 北京市海淀区中关村文化交流中心北苑路北10002路
-----------下面我们来探究通过装饰器来使得私有化属性可以被修改-----------------------
实例对象属性集合: {'name': '小张', 'age': 50, '_ExchangeMeetingClassSet__Operation': '世界艺术交流展会'}
访问类私有属性[__Operation]: 世界艺术交流展会
六: Python中父子类面向对象编程思想
在Python中,父类可以派生出多个子类,也就是一个父类可以被多个子类继承;子类可以继承父类的属性和方法
不像java,只允许一个类继承单个类,不允许同时继承多个类;但是Python中运行一个类继承多个类;
即子类可以继承父类的所有的属性及方法:
通过父子类的编程思想来设计架构,这是面向对象的思想。对应全部都遵守的共性,用父类来描述:对于满足部分共性的对象,用多个子类来描述
继承的语法:
class + 类名(父类的类名1,父类的类名1,.....父类的类名n):
语句块1
语句块2
语句块3
.
.
.
语句块n,
当括号内的父类名称是单个的时候,就是单继承否则就是多继承
(1)学习java的小伙伴知道,覆盖是指子类重写父类的方法,重写发生在子类与父类之间,当父类的方法实现的业务不能满足我们需要的时候,此时我们可以通过重写
父类的方法来实现我们的业务逻辑;通过拓展父类的方法,可以在不改变父类的前提下,不会影响其他继承同一父类的类产生影响;
当子类的方法与父类的方法同名时且参数表列相同时,父类的方法也将失效; 通常子类覆写父类方法的同时,需要调用下父类的被覆写的方法;
这种情况下,可以通过以下的方式调用父类方法:
FatherClassName.method(self,arguments)
(2)Python中采用了C3线性化算法去检索父类,保证每个父类只检索一次,以避免检索过程陷入死循环
# -*- coding:utf8 -*- print("类的认知:") print("Python中类的继承关系: 派生与继承时针对子类与父类而言") ''' 在Python中,父类可以派生出多个子类,也就是一个父类可以被多个子类继承;子类可以继承父类的属性和方法 不像java,只允许一个类继承单个类,不允许同时继承多个类;但是Python中运行一个类继承多个类; 即子类可以继承父类的所有的属性及方法: 通过父子类的编程思想来设计架构,这是面向对象的思想。对应全部都遵守的共性,用父类来描述:对于满足部分共性的对象,用多个子类来描述 继承的语法: class + 类名(父类的类名1,父类的类名1,.....父类的类名n): 语句块1 语句块2 语句块3 . . . 语句块n, 当括号内的父类名称是单个的时候,就是单继承否则就是多继承 ''' print('-----------------------------------认知升维----------------------------------------') print("-----------------------------------来认识覆盖|重写----------------------------------") print(""" (1)学习java的小伙伴知道,覆盖是指子类重写父类的方法,重写发生在子类与父类之间,当父类的方法实现的业务不能满足我们需要的时候,此时我们可以通过重写 父类的方法来实现我们的业务逻辑;通过拓展父类的方法,可以在不改变父类的前提下,不会影响其他继承同一父类的类产生影响; 当子类的方法与父类的方法同名时且参数表列相同时,父类的方法也将失效; 通常子类覆写父类方法的同时,需要调用下父类的被覆写的方法; 这种情况下,可以通过以下的方式调用父类方法: FatherClassName.method(self,arguments) (2)Python中采用了C3线性化算法去检索父类,保证每个父类只检索一次,以避免检索过程陷入死循环 """) # 继承:inherit class FatherClass: """ father class and children class inherit relation""" __operationActivity = "scientist" # 拓展init方法,完成初始化工作;将传入的参数赋值给成员变量name,age def __init__(self, name, age): self.name = name self.age = age # 普通的成员方法 def showFatherInfo(self): # 类的私有化成员属性,在本类中可以使用self.属性名的方式访问 print("operationActivity: ", self.__operationActivity) return self.name, self.age # 提供一个公有的方法给外界访问类私有属性 def getOperationActivity(self): return self.__operationActivity # 单继承 class GirlChildrenClass(FatherClass): """A GirlChildrenClass Class""" def showFatherInfo(self): # 子类重写父类的方法,并调用父类被重写的方法 FatherClass.showFatherInfo(self) print("女孩叫:", self.name, " 年龄: ", self.age) myGirlFather = GirlChildrenClass('小米', 200) myGirlFather.showFatherInfo() print("访问类属性__operationActivity私有属性: ", myGirlFather.getOperationActivity()) print("子类的相关属性: ", myGirlFather.__dict__) print(""" 子类不能继承父类的私有属性: """) print("-------------------------------------------------------------------------------------") print() print('-----------------------------------------多继承----------------------------------') # 定义一个字类 class FemaleFatherClass(FatherClass): """A FemaleFatherClass class""" def showFatherInfo(self): # 定义一个成员函数 print(self.name, ":", self.age, ", female") # 该成员函数返回成员的信息 FatherClass.showFatherInfo(self) # 调用其父类的showFatherInfo方法 # 定义一个子类 class RetireFatherClass(FatherClass): """A RetireFatherClass class""" def showFatherInfo(self): # 定义成员函数 FatherClass.showFatherInfo(self) # 调用父类的showFatherInfo方法 print("retire worker") # 该成员函数返回该类的成员变量 # 多继承 class ThisFatherClass(FemaleFatherClass, RetireFatherClass): """A ThisFatherClass class""" # 定义这类的说明字符串 def showFatherInfo(self): # 定义一个成员函数 print("the member detail as follow:") # 该成员函数返回这类的成员变量 # 调用父类的showFatherInfo方法 FemaleFatherClass.showFatherInfo(self) RetireFatherClass.showFatherInfo(self) myThisInfo = ThisFatherClass("杨哥", 26) myThisInfo.showFatherInfo() print() print() print() print("myThisInfo.showFatherInfo()输出如下内容:") print(""" the member detail as follow: 杨哥 : 26 , female operationActivity: scientist operationActivity: scientist retire worker """) print(""" 通过输出内容,发现父类FatherClass类中的showFatherInfo方法被调用了两从,在实际编程中 这种父类函数被自动调用多次的情况一定要避免,如果showFatherInfo方法时一些申请资源之类的操作 这种写法会导致资源泄露,会严重影响程序的性能; 针对这种情况: 通常我们使用super函数,实现多继承中父类的调用 """) # 定义一个字类 class SubFemaleFatherClass(FatherClass): """A FemaleFatherClass class""" def showFatherInfo(self): # 定义一个成员函数 print(self.name, ":", self.age, ", female") # 该成员函数返回成员的信息 super().showFatherInfo() # 调用其父类的showFatherInfo方法 # 定义一个子类 class SubRetireFatherClass(FatherClass): """A RetireFatherClass class""" def showFatherInfo(self): # 定义成员函数 super().showFatherInfo() # 调用父类的showFatherInfo方法 print("retire worker") # 该成员函数返回该类的成员变量 # 多继承 class SubThisFatherClass(SubFemaleFatherClass, SubRetireFatherClass): """A ThisFatherClass class""" # 定义这类的说明字符串 def showFatherInfo(self): # 定义一个成员函数 print("super()函数返回值: ", super()) print("the member detail as follow:") # 该成员函数返回这类的成员变量 # 调用父类的showFatherInfo方法 super().showFatherInfo() print(""" 注意: 使用super函数时,对父类的方法使用会自动传入self.无需再传入self,否则报错; """) print('----------------------------------------------') myThisInfo = SubThisFatherClass("杨大侠", 20) myThisInfo.showFatherInfo() print(""" 使用super()函数后,多继承父类的showFatherInfo()方法只会调用一次 super()函数返回值: <super: <class 'SubThisFatherClass'>, <SubThisFatherClass object>> the member detail as follow: 杨大侠 : 20 , female operationActivity: scientist retire worker """)
七:父子类面向对象编程思想运行效果
D:\program_file_worker\anaconda\python.exe D:\program_file_worker\python_source_work\SSO\grammar\oop\ClassInheritBaseClass.py
类的认知:
Python中类的继承关系: 派生与继承时针对子类与父类而言
-----------------------------------认知升维----------------------------------------
-----------------------------------来认识覆盖|重写----------------------------------(1)学习java的小伙伴知道,覆盖是指子类重写父类的方法,重写发生在子类与父类之间,当父类的方法实现的业务不能满足我们需要的时候,此时我们可以通过重写
父类的方法来实现我们的业务逻辑;通过拓展父类的方法,可以在不改变父类的前提下,不会影响其他继承同一父类的类产生影响;
当子类的方法与父类的方法同名时且参数表列相同时,父类的方法也将失效; 通常子类覆写父类方法的同时,需要调用下父类的被覆写的方法;
这种情况下,可以通过以下的方式调用父类方法:
FatherClassName.method(self,arguments)
(2)Python中采用了C3线性化算法去检索父类,保证每个父类只检索一次,以避免检索过程陷入死循环operationActivity: scientist
女孩叫: 小米 年龄: 200
访问类属性__operationActivity私有属性: scientist
子类的相关属性: {'name': '小米', 'age': 200}子类不能继承父类的私有属性:
-------------------------------------------------------------------------------------
-----------------------------------------多继承----------------------------------
the member detail as follow:
杨哥 : 26 , female
operationActivity: scientist
operationActivity: scientist
retire workermyThisInfo.showFatherInfo()输出如下内容:
the member detail as follow:
杨哥 : 26 , female
operationActivity: scientist
operationActivity: scientist
retire worker
通过输出内容,发现父类FatherClass类中的showFatherInfo方法被调用了两从,在实际编程中
这种父类函数被自动调用多次的情况一定要避免,如果showFatherInfo方法时一些申请资源之类的操作
这种写法会导致资源泄露,会严重影响程序的性能;
针对这种情况:
通常我们使用super函数,实现多继承中父类的调用
注意:
使用super函数时,对父类的方法使用会自动传入self.无需再传入self,否则报错;
----------------------------------------------
super()函数返回值: <super: <class 'SubThisFatherClass'>, <SubThisFatherClass object>>
the member detail as follow:
杨大侠 : 20 , female
operationActivity: scientist
retire workerProcess finished with exit code 0