多态
1. 什么是多态?
多态指的是同一种类型的事物, 不同的形态.
2. 多态的目的:
"多态" 也称之为 "多态性", 目的是为了 在不知道对象具体类型的情况下, 统一对象调用方法的规范(比如: 名字).
多态的表现 "形式之一" 就是继承:
- 先抽象, 再继承
父类: 定制一套统一的规范.(比如: 方法名统一)
子类: 遵循父类的统一的规范.(比如: 子类遵循父类方法名的统一)
注意: 在 python 中不会强制限制 子类 必须要遵循 父类 的规范, 所以出现了抽象类.
- # 动物类
- class Animal:
- # 方法 吃
- def eat(self):
- pass
- # 方法 叫
- def speak(self):
- pass
- # 猪类
- class Pig(Animal):
- def eat(self):
- print('bia 唧...')
- def speak(self):
- print('哼哼哼...')
- # 猫类
- class Cat(Animal):
- def eat(self):
- print('咬 ji 咬 ji....')
- def speak(self):
- print('喵喵喵...')
- # 狗类
- class Dog(Animal):
- def eat(self):
- print('舔 ji 舔 ji...')
- def speak(self):
- print('汪汪汪...')
- animal1 = Dog()
- animal2 = Pig()
- animal3 = Cat()
- # 让动物们叫起来
- animal1.speak()
- animal2.speak()
- animal3.speak()
抽象类
1. 什么是抽象类?
在 python 内置的 abc 模块中, 有一个抽象类.
2. 抽象类的作用:
让子类必须遵循父类的编写规范.
3. 如何实现抽象类
- 父类需要继承 abc 模块中, metaclass=abc.ABCMeta
- 在父类的方法中, 需要装饰上 abc.abstractmethod
注意: 在 python 中不推荐使用抽象类.
注意: 子类必须按照父类的方法编写规范, 缺一不可.(只要父类中有几个抽象方法, 子类就必须要定义几个)
- import abc
- # 父类
- class Animal(metaclass=abc.ABCMeta):
- # 方法 吃
- @abc.abstractmethod
- def eat(self):
- pass
- # 方法 叫
- @abc.abstractmethod
- def speak(self):
- pass
- # 猪类
- class Pig(Animal):
- def run(self):
- pass
- def eat(self):
- print('bia 唧...')
- def speak(self):
- print('哼哼哼...')
- print(Pig.__dict__)
- print(Animal.__dict__)
- pig_obj = Pig()
鸭子类型
1. 什么是鸭子类型?
不同的对象, 只要长得像鸭子, 动作行为像鸭子, 那它就是鸭子!
鸭子类型是多态的一种表现形式.
2. 为什么要有鸭子类型?
不同对象, 先抽象出相同类型的方法, 给他们定制一套统一的规范.
所有的类, 在定义时都按照统一的规范进行编写.
- 多态的三种表现形式:
- 继承父类 ****
- 耦合度高, 程序的可扩展性低
- 继承抽象类 ***
- 耦合度极高, 程序的可扩展性极低
- 鸭子类型: *****
- 耦合度低, 程序的可扩展性高
注意: 在 python 中, 强烈推荐使用鸭子类型.
- # 猪类
- class Pig:
- def eat(self):
- print('bia 唧...')
- def speak(self):
- print('哼哼哼...')
- # 猫类
- class Cat:
- def eat(self):
- print('咬 ji 咬 ji...')
- def speak(self):
- print('喵喵喵...')
- # 狗类
- class Dog:
- def eat(self):
- print('舔 ji 舔 ji...')
- def speak(self):
- print("汪汪汪...")
多态之炫技
- # 猪类
- class Pig:
- def eat(self):
- print('bia 唧...')
- def speak(self):
- print('哼哼哼...')
- # 猫类
- class Cat:
- def eat(self):
- print('咬 ji 咬 ji...')
- def speak(self):
- print('喵喵喵...')
- # 狗类
- class Dog:
- def eat(self):
- print('舔 ji 舔 ji...')
- def speak(self):
- print("汪汪汪...")
- dog = Dog()
- pig=Pig()
- cat=Cat()
- # 多态之炫技
- def SPEAK(animal):
- animal.speak()
- SPEAK(dog)
- SPEAK(cat)
- SPEAK(pig)
- str1 = 'tank is very handsome!!!'
- list1 = ['tank', 'is', 'very', 'handsome!!!']
- # 自定义统计长度函数
- def LEN(obj):
- return obj.__len__()
- print(LEN(str1)) # 24
- print(LEN(list1)) # 4
classmethod 与 staticmethod
classmethod 与 staticmethod 都是 python 解释器内置的装饰器. *******
classmethod:
是一个装饰器, 给在类内部定义方法中装饰, 将类内部的方法变为 "类的绑定方法".
staticmethod:
翻译: 静态方法
是一个装饰器, 给在类内部定义方法中装饰, 将类内部的方法变为 "非绑定方法".
- 对象的绑定方法:
- 由对象来调用, 由谁来调用, 会将谁 (对象) 当做第一个参数传入.
- 类的绑定方法:
- 由类来调用, 由谁来调用, 会将谁 (类) 当做第一个参数传入.
- 非绑定方法:
- 可以由对象或类来调用, 谁来调用都是一个普通方法(普通函数), 方法需要传入几个参数, 就得传入几个.
- # classmethod_Demo:
- class DB:
- __data = 'tank is very handsome!!!'
- def __init__(self, user, pwd, role):
- self.user = user
- self.pwd = pwd
- self.role = role
- # @classmethod
- # def init(cls, user, pwd, role): # cls --》指的是类
- # # 在类方法内部调用类产生一个实例 ---》 对象
- # return cls(user, pwd, role)
- # 查看数据方法
- @classmethod
- def check_db(cls, user, pwd, role): # cls --》指的是类
- # 在类方法内部调用类产生一个实例 ---》 对象
- obj = cls(user, pwd, role)
- # 1. 查看数据前, 必须要通过校验
- if obj.user == 'tank' and obj.pwd == '123' and obj.role == 'admin':
- print('检验通过..')
- print(cls.__data)
- return cls.__data
- DB.check_db('tank', '123', 'admin')
- obj=DB('tank','123','admin')
- obj.check_db('tank','123','admin') # 也可以, 第一个传入参数依然是类, 但没什么意义
- # staticmethod_Demo:
- class Foo:
- @staticmethod
- def func(res):
- print(res)
- obj = Foo()
- # 对象调用非绑定方法
- obj.func(123)
- # 类调用非绑定方法
- Foo.func(1234)
uuid 用于产生随机字符串的模块
- import uuid # 用于产生随机字符串的模块
- # 由时间戳以及某种算法组合而成, 会产生一串世界上独一无二字符串.
- print(uuid.uuid4()) # f93f9c3b-eef4-4001-922e-2124b48ca7ab
内置模块: isinstance 与 issubclass
isinstance 与 issubclass 是 python 的内置模块: *******
- isinstance: 判断一个对象是否是另一个类的实例.
- 如果是: True
- 如果不是: False
- issubclass: 判断一个类是否是另一个类的子类.
- 如果是: True
- 如果不是: False
- # isinstance:
- class Foo:
- pass
- class Boo:
- pass
- foo_obj = Foo()
- boo_obj = Boo()
- print(isinstance(foo_obj, Foo)) # True
- print(isinstance(boo_obj, Foo)) # False
- # issubclass
- class Father:
- pass
- class Sub(Father):
- pass
- class Foo:
- pass
- print(issubclass(Sub, Father)) # True
- print(issubclass(Foo, Father)) # False
反射
反射: *******
反射指的是通过 "字符串" 对 对象的属性进行操作.
- hasattr: 通过 "字符串" 判断对象的属性或方法是否存在.
- getattr: 通过 "字符串" 获取对象的属性或方法.
- setattr: 通过 "字符串" 设置对象的属性或方法.
- delattr: 通过 "字符串" 删除对象的属性或方法.
- # 注意: 反射的四个方法是 python 内置的.
- class Foo:
- def __init__(self, x, y):
- self.x = x
- self.y = y
- foo_obj = Foo(10, 20)
- # hasattr
- # 通过字符串 x 判断对象中是否有 x 属性
- print(hasattr(foo_obj, 'x')) # True
- print(hasattr(foo_obj, 'y')) # True
- print(hasattr(foo_obj, 'z')) # False
- # getattr
- res = getattr(foo_obj, 'x')
- print(res) # 10
- # 若属性不存在, 则返回默认值
- res = getattr(foo_obj, 'z', '默认值')
- print(res) # 默认值
- # setattr
- setattr(foo_obj,'x',40)
- print(getattr(foo_obj,'x')) # 40
- # 为 foo_obj 设置一个属性 z, 值为 30
- setattr(foo_obj, 'z', 30)
- print(hasattr(foo_obj, 'z')) # True
- # delattr
- delattr(foo_obj, 'x')
- print(hasattr(foo_obj, 'x')) # False
- # 反射应用:
- class FileControl:
- def run(self):
- while True:
- # 让用户输入上传或下载功能的命令:
- user_input = input('请输入 上传(upload) 或 下载(download) 功能:').strip()
- # 通过用户输入的字符串判断方法是否存在, 然后调用相应的方法
- if hasattr(self, user_input):
- func = getattr(self, user_input)
- func()
- else:
- print('输入有误!')
- def upload(self):
- print('文件正在上传...')
- def download(self):
- print('文件正在下载...')
- file_control_obj = FileControl()
- file_control_obj.run()
以下为验证, 反射中将输入输入字符创转化为方法
- # 代码同上, 用来测试反射里面类型变化
- class choose:
- def run(self):
- while True:
- cmd = input('请输入命令:').strip()
- if hasattr(self,cmd):
- print(getattr(self,cmd)) # 把字符串转化为方法
- # <bound method choose.load of <__main__.choose object at 0x00000000022A5F28>>
- print(type(getattr(self,cmd)))
- # <class 'method'>
- getattr(self,cmd)() # 运行方法
- else:
- print('输入有误')
- def load(self):
- print('load')
- def down(self):
- print('down')
- obj = choose()
- print(type(obj.load)) # <class 'method'>
- obj.run()
来源: http://www.bubuko.com/infodetail-3307739.html