368 lines
8.8 KiB
Plaintext
368 lines
8.8 KiB
Plaintext
=================================
|
||
Notes
|
||
Author: Flora Chen
|
||
-_- -_- -_- -_- -_- -_- -_- -_-
|
||
=================================
|
||
|
||
******类属性的分类******
|
||
类属性的分类:
|
||
1. 公有属性:既可以在类内部使用,又可以在类的外部被调用。
|
||
2. 私有属性:使用双下划线开头。只能在类外部使用,在类外面无法被调用。
|
||
|
||
示例:
|
||
class Cat:
|
||
# 公有属性
|
||
attr = 'I have tail'
|
||
# 私有属性
|
||
__attr = 'I have 4 legs'
|
||
|
||
def print_attr(self):
|
||
print('在类的内部访问公有属性', self.attr)
|
||
print('在类的内部访问公有属性', self.__attr)
|
||
|
||
Kitty = Cat()
|
||
|
||
print('在类的外部访问公有属性', Kitty.attr)
|
||
|
||
# 在类外部调用私有属性会报错: AttributeError: 'Cat' object has no attribute '__attr'
|
||
# print('在类的外部访问公有属性', Kitty.__attr)
|
||
|
||
Kitty.print_attr()
|
||
|
||
******类定义的两种方式******
|
||
# 这两种定义类的方式无差别
|
||
# 类定义的第一种方式:不写继承的父类,默认继承object。
|
||
class MyTest:
|
||
pass
|
||
|
||
# 类定义的第二种方式:在类名的括号后面指定继承object这个类。
|
||
class MyClass(object):
|
||
pass
|
||
|
||
# object: python中所有类的基类(祖宗类)
|
||
******类的继承******
|
||
子类通过继承父类,能够获取父类中定义的所有属性和方法(私有属性除外)。
|
||
注意:父类不能使用子类的属性和方法。
|
||
|
||
继承的作用:简化代码,提高代码的重用性。
|
||
|
||
示例:
|
||
未用到继承之前的代码:
|
||
class PhoneV1(object):
|
||
def call(self):
|
||
print('打电话的功能')
|
||
|
||
class PhoneV2(object):
|
||
def call(self):
|
||
print('打电话的功能')
|
||
|
||
def listen_music(self):
|
||
print('听音乐的功能')
|
||
|
||
def send_message(self):
|
||
print('发短信的功能')
|
||
|
||
class PhoneV3(object):
|
||
def call(self):
|
||
print('打电话的功能')
|
||
|
||
def listen_music(self):
|
||
print('听音乐的功能')
|
||
|
||
def send_message(self):
|
||
print('发短信的功能')
|
||
|
||
def we_chat(self):
|
||
print('聊微信的功能')
|
||
|
||
def plag_game(self):
|
||
print('玩游戏的功能')
|
||
|
||
用到继承之后的代码:
|
||
class PhoneV1(object):
|
||
def call(self):
|
||
print('打电话的功能')
|
||
|
||
class PhoneV2(PhoneV1):
|
||
def listen_music(self):
|
||
print('听音乐的功能')
|
||
|
||
def send_message(self):
|
||
print('发短信的功能')
|
||
|
||
class PhoneV3(PhoneV2):
|
||
def we_chat(self):
|
||
print('聊微信的功能')
|
||
|
||
def play_game(self):
|
||
print('玩游戏的功能')
|
||
|
||
# v1对应的类
|
||
print('------v1对应的类------')
|
||
v1 = PhoneV1()
|
||
v1.call()
|
||
# 父类不能调用子类的方法
|
||
# v1.listen_music() # 报错:AttributeError: 'PhoneV1' object has no attribute 'listen_music'
|
||
|
||
# v2对应的类
|
||
print('------v2对应的类------')
|
||
v2 = PhoneV2()
|
||
# 子类可以调用父类的方法
|
||
v2.call()
|
||
v2.listen_music()
|
||
v2.send_message()
|
||
|
||
# v3对应的类
|
||
print('------v3对应的类------')
|
||
v3 = PhoneV3()
|
||
v3.call()
|
||
v3.listen_music()
|
||
v3.send_message()
|
||
v3.we_chat()
|
||
v3.play_game()
|
||
|
||
******重写父类方法******
|
||
在子类中定义跟父类同名的方法就是重写父类方法。
|
||
class PhoneV1(object):
|
||
def call(self):
|
||
print('打电话的功能')
|
||
|
||
class PhoneV2(PhoneV1):
|
||
def listen_music(self):
|
||
print('听音乐的功能')
|
||
|
||
def send_message(self):
|
||
print('发短信的功能')
|
||
# 重写父类的方法
|
||
def call(self):
|
||
print('打视频电话的功能')
|
||
|
||
class PhoneV3(PhoneV2):
|
||
def we_chat(self):
|
||
print('聊微信的功能')
|
||
|
||
def play_game(self):
|
||
print('玩游戏的功能')
|
||
|
||
print('------v1对应的类------')
|
||
v1 = PhoneV1()
|
||
v1.call() # 输出结果:打电话的功能
|
||
|
||
print('------v2对应的类------')
|
||
v2 = PhoneV2()
|
||
# 子类可以调用父类的方法
|
||
v2.call() # 输出结果:打视频电话的功能
|
||
|
||
print('------v3对应的类------')
|
||
v3 = PhoneV3()
|
||
v3.call() # 输出结果:打视频电话的功能
|
||
|
||
******调用被重写的父类方法******
|
||
方式一:父类名.方法名(self)
|
||
方式二:super().方法名
|
||
示例:
|
||
class PhoneV1(object):
|
||
def call(self):
|
||
print('打电话的功能')
|
||
|
||
class PhoneV2(PhoneV1):
|
||
def we_chat(self):
|
||
print('聊微信的功能')
|
||
|
||
def play_game(self):
|
||
print('玩游戏的功能')
|
||
# 重写父类的方法
|
||
def call(self):
|
||
print('打视频电话的功能')
|
||
print('**********接下来想打语音电话')
|
||
# 调用父类里面的call()
|
||
# 方式一:父类名.方法名(self)
|
||
PhoneV1.call(self)
|
||
# 方式二:super().方法名
|
||
super().call()
|
||
|
||
v2 = PhoneV2()
|
||
v2.call()
|
||
|
||
|
||
******super()的应用场景******
|
||
主要是代码的扩展,扩展新功能。
|
||
示例:
|
||
class MyClass:
|
||
def __init__(self, a, b):
|
||
self.a = a
|
||
self.b = b
|
||
|
||
def number(self):
|
||
print('a+b=', self.a + self.b)
|
||
|
||
|
||
class MyClassV2(MyClass):
|
||
def number(self):
|
||
# 调用父类原有的方法
|
||
super().number()
|
||
# 在原有方法的基础上扩展新功能
|
||
print('a+b=', self.a / self.b)
|
||
|
||
|
||
m = MyClassV2(11, 22)
|
||
m.number()
|
||
|
||
|
||
******动态获取属性******
|
||
getattr获取类属性:
|
||
参数1:类
|
||
参数2:属性名
|
||
参数3:默认值。如果属性不存在,则返回该值
|
||
|
||
示例:
|
||
# 示例1
|
||
class TestData:
|
||
url = 'http://www.baidu.com'
|
||
method = 'get'
|
||
|
||
# getattr获取类属性
|
||
res = getattr(TestData, 'url')
|
||
print(res) # 输出结果:http://www.baidu.com
|
||
|
||
res1 = getattr(TestData, 'result', 'python')
|
||
print(res1) # 输出结果:python
|
||
|
||
# 示例2:
|
||
class TestData:
|
||
url = 'http://www.baidu.com'
|
||
method = 'get'
|
||
|
||
name = input('请输入你要获取的属性名:')
|
||
|
||
# getattr获取类属性
|
||
res = getattr(TestData, name, 'None')
|
||
print(res) # 输出结果:http://www.baidu.com
|
||
|
||
******动态设置属性******
|
||
setattr设置属性值:
|
||
参数1:类
|
||
参数2:属性名
|
||
参数3:属性值
|
||
|
||
示例1:
|
||
# 类外面定义类属性
|
||
# 方式一:类.属性名=属性值
|
||
TestData.result = 'Pass'
|
||
print(TestData.result)
|
||
|
||
# 方式二:动态setattr设置属性
|
||
setattr(TestData, 'para', 'username')
|
||
print(TestData.para) # 输出结果:username
|
||
|
||
示例2:
|
||
class TestData:
|
||
url = 'http://www.baidu.com'
|
||
method = 'get'
|
||
|
||
# 将下面2个列表,title作为属性名,data作为属性值,一一对应起来
|
||
title = ['name', 'age', 'gender']
|
||
data = ['flora', 26, 'female']
|
||
|
||
# 以下方法是不可取的,会报错:AttributeError: type object 'TestData' has no attribute 'title'
|
||
# TestData.title[0] = data[0]
|
||
# print(TestData.title[0])
|
||
|
||
# setattr(TestData, title[0], data[0])
|
||
# setattr(TestData, title[1], data[1])
|
||
# setattr(TestData, title[2], data[2])
|
||
|
||
for i in range(len(title)):
|
||
setattr(TestData, title[i], data[i])
|
||
|
||
print(TestData.name, TestData.age, TestData.gender)
|
||
# 输出结果:flora 26 female
|
||
|
||
|
||
******动态删除属性******
|
||
delattr动态删除属性:
|
||
参数1:类
|
||
参数2:属性名
|
||
|
||
示例:
|
||
class TestData:
|
||
url = 'http://www.baidu.com'
|
||
method = 'get'
|
||
|
||
# 方式一:关键字del
|
||
del TestData.url
|
||
print(TestData.url) # 报错:AttributeError: type object 'TestData' has no attribute 'url'
|
||
|
||
# 方式二:delattr
|
||
name = input('请输入你要删除的属性:')
|
||
delattr(TestData, name)
|
||
|
||
******判断属性是否存在******
|
||
hasattr判断属性是否存在:
|
||
参数1:类名
|
||
参数2:属性名
|
||
如果属性存在,返回True;如果属性不存在,返回False
|
||
示例:
|
||
class TestData:
|
||
url = 'http://www.baidu.com'
|
||
method = 'get'
|
||
|
||
del TestData.url
|
||
|
||
res = hasattr(TestData, 'url')
|
||
print(res) # 输出结果:False
|
||
res1 = hasattr(TestData, 'method')
|
||
print(res1) # 输出结果:True
|
||
|
||
******多继承******
|
||
子类可以继承多个父类,子类都可以用到继承的父类中的属性和方法。
|
||
示例:
|
||
class BaseA(object):
|
||
attr_a = 100
|
||
def func_a(self):
|
||
print('func_a----------aaa')
|
||
|
||
class BaseB(object):
|
||
attr_b = 900
|
||
def func_b(self):
|
||
print('func_b----------bbb')
|
||
|
||
class MyTest(BaseA, BaseB):
|
||
pass
|
||
|
||
m = MyTest()
|
||
print(m.attr_a)
|
||
print(m.attr_b)
|
||
|
||
m.func_a()
|
||
m.func_b()
|
||
|
||
注意:
|
||
如果子类继承的父类里面都有相同的方法,在调用的时候,会先找第一个父类的方法,找到了就不会继续找了,没找到就会继续找下一个父类的方法。
|
||
如果子类自己也有跟父类相同的方法,在调用的时候,子类会优先使用自己的方法,不会去找父类的方法了。
|
||
示例:
|
||
class BaseA(object):
|
||
attr_a = 100
|
||
def func_a(self):
|
||
print('func_a----------aaa')
|
||
|
||
def func(self):
|
||
print('func_ab----------ab')
|
||
|
||
class BaseB(object):
|
||
attr_b = 900
|
||
def func_b(self):
|
||
print('func_b----------bbb')
|
||
|
||
def func(self):
|
||
print('func_bb----------bb')
|
||
|
||
class MyTest(BaseA, BaseB):
|
||
pass
|
||
# def func(self):
|
||
# print('func_cb----------cb')
|
||
|
||
m = MyTest()
|
||
m.func()
|
||
|