Python学习
类成员的继承和重写
1.成员继承:子类继承了父类除构造方法之外的所有成员
2.方法重写:子类可以重新定义父类中的方法,这样会覆盖父类的方法,也称为重写
下面是Demo
class person:
def __init__(self,name,age):
self.name = name
self.__age = age
def say_age(self):
print('我的年龄:',self.__age)
def say_introduce(self):
print('我的名字是{0}'.format(self.name))
class stident(person):
def __init__(self,name,age,score):
person.__init__(self,name,age)#必须显示的调用父类初始化方法,不然解释器不会去调用
def say_introduce(self):
'''重写父类的方法'''
print('报告老师,我的名字是:{0}'.format(self.name))
s = stident('高崎',18,80)
s.say_age()
s.say_introduce()
E:\python\python37\python.exe E:/python/PycharmProjects/pythonProject3/类继承的方法和重写.py
我的年龄: 18
报告老师,我的名字是:高崎
Process finished with exit code 0
object根类_dir()
通过类的方法mro()或者类的属性_mro_可以输出这个类的层次结构
objectl类是所有类的父类,因此所有的类都有object类的属性和方法,我们显然有必要研究一下object类的结构,对于我们继续深入学习很有好处
_dir()查看对象属性
以上我们可以发现这样几个要点:
1.person对象增加了6个属性:dict module weakref age name say_age
2.object的所有属性,person类作为object的子类,显然包含了所有的属性
3.我们打印age,name,say_age,发现say_age虽然是方法,实际上也是属性,只不过这个属性的类型是method而已
下面是Demo
#测试object根类
class person:
def __init__(self,name,age):
self.name = name
self.age = age
def say_age(self):
print(self.name,'年龄是:',self.age)
obj = object()
print(dir(obj))
s2 = person('高崎',18)
print(dir(s2))
E:\python\python37\python.exe E:/python/PycharmProjects/pythonProject3/object根类.py
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'age', 'name', 'say_age']
Process finished with exit code 0
重写_str_()方法
object重写_str_()方法。
下面是Demo
#测试object重写_str_()方法
class person: #默认继承object方法
def __init__(self,name):
self.name = name
def __str__(self):
return '名字是:{0}'.format(self.name)
p = person('高崎')
print(p)
多重继承
python支持多重继承,一个子类可以有多个直接父类,这样就具备了多个父类的特点,但是由于,这样会被类的整体层次,搞的异常复杂,尽量避免使用,
下面是Demo
#多重继承
class a:
def aa(self):
print('aa')
class b:
def bb(self):
print('bb')
class c(b,a):
def cc(self):
print('cc')
c = c()
c.cc()
c.bb()
E:\python\python37\python.exe E:/python/PycharmProjects/pythonProject3/多重继承.py
cc
bb
Process finished with exit code 0
MRO()函数
python支持多继承,如果父类中有相同名字的方法,在子类没有指定父类名时,解释器将从左向右按顺序搜素
MRO(Method Resolution Order):方法解析顺序,我们可以通过mro()方法获得类的层次结构,方法解析顺序也是按照这个类的层次结构寻找的
下面是Demo
#多重继承
class A:
def aa(self):
print('aa')
class B:
def bb(self):
print('bb')
class C(B,A):
def cc(self):
print('cc')
c = C()
c.cc()
c.bb()
#测试MRO()方法
print(C.mro())#打印的层次结构
c.say()#解释器寻找方式时从左往右的方式寻找,此是会执行B中的say()
E:\python\python37\python.exe E:/python/PycharmProjects/pythonProject3/多重继承.py
cc
bb
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
Traceback (most recent call last):
File "E:/python/PycharmProjects/pythonProject3/多重继承.py", line 19, in <module>
c.say()#解释器寻找方式时从左往右的方式寻找,此是会执行B中的say()
AttributeError: 'C' object has no attribute 'say'
Process finished with exit code 1
super()获取父类定义
在子类中,如果想要获得父类的方法时,我们可以通过super()来做,super()代表父类的定义,不是父类对象
下面是Demo
#测试super()获取父类定义,而不是父类的对象
class a:
def say(self):
print('a',self)
class b(a):
def say(self):
# a.say(self)
super().say()
print('b',self)
b().say()
E:\python\python37\python.exe E:/python/PycharmProjects/pythonProject3/super()获取父类定义.py
a <__main__.b object at 0x0000026231AD0E48>
b <__main__.b object at 0x0000026231AD0E48>
Process finished with exit code 0
多态
多态时指同一个方法调用由于对象不同而产生了不同的行为
关于多态需要注意的要点:
1.多态是方法的多态,属性没有多态
2.多态的存在有两个必要条件,继承,方法重写
下面是Demo
#多态
class Man:
def eat(self):
print('饿了,吃饭啦')
class Chinese(Man):
def eat(self):
print('中国人用筷子吃饭')
class English(Man):
def eat(self):
print('英国人用叉子吃饭')
class Indian(Man):
def eat(self):
print('印度人用右手吃饭')
def manEat(m):
if isinstance(m,Man):
m.eat()#多态,一个方法调用,根据对象不同调用不同的方法
else:
print('不能吃饭')
manEat(Chinese())
manEat(English())
E:\python\python37\python.exe E:/python/PycharmProjects/pythonProject3/多态.py
中国人用筷子吃饭
英国人用叉子吃饭
Process finished with exit code 0
特殊方法和运算符重载
python的运算符实际上是通过调用对象的特殊方法实现的
下面是Demo
#运算符的重载
class person:
def __init__(self,name):
self.name = name
def __add__(self, other):
if isinstance(other,person):
return '{0}--{1}'.format(self.name,other.name)
else:
return '不是同类型,不能相加'
def __mul__(self, other):
if isinstance(other,int):
return self.name*other
else:
return '不是同类,不能相加'
p1 = person('袁少旭')
p2 = person('苏小红')
x = p1+p2
print(x)
print(p2*30)
E:\python\python37\python.exe E:/python/PycharmProjects/pythonProject3/特殊方法和运算符重载.py
袁少旭--苏小红
苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红苏小红
Process finished with exit code 0
特殊属性
python对象包含了很多双下划线开始和结束的属性,这些是特殊属性,有特殊用法
下面是Demo
#多重继承
class A:
def aa(self):
print('aa')
def say(self):
print('say AAA')
class B:
def bb(self):
print('bb')
def say(self):
print('say BBB')
class C(B,A):
def __init__(self,nn):
self.nn = nn
def cc(self):
print('cc')
c = C(32)
c.cc()
c.bb()
#测试MRO()方法
print(C.mro())#打印的层次结构
c.say()#解释器寻找方式时从左往右的方式寻找,此是会执行B中的say()
print(dir(c))
print(c.__dict__)
print(c.__class__)
print(C.__bases__)
print(C.mro())
print(A.__subclasses__())
E:\python\python37\python.exe E:/python/PycharmProjects/pythonProject3/多重继承.py
cc
bb
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
say BBB
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', 'aa', 'bb', 'cc', 'nn', 'say']
{'nn': 32}
<class '__main__.C'>
(<class '__main__.B'>, <class '__main__.A'>)
[<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>]
[<class '__main__.C'>]
Process finished with exit code 0