多继承真正的方式:mixins机制
mixins机制核心:就是在多继承背景下尽可能地提升多继承的可读性
ps:让多继承满足人的思维习惯=》什么"是"什么
补充:通常Mixin结果的类放在左边
在子类派生的新方法中如何重用父类功能?
方式一:指名道姓的调用某一个类下的函数,不依赖于继承关系
方式二:super()调用父类提供给自己的方法=》严格依赖继承关系
# 调用super()会得到一个特殊的对象,该对象会参照发起属性查找的那个类的mro,去当前类的父类中找属性
什么是多态?:同一种事物具有多种形态
2、为何要有多态=》多态会带来什么样的特性,多态性
多态性指的是可以在不考虑对象具体类型的情况下而直接使用对象
多态性的好处在于增强了程序的灵活性和可扩展性,比如通过继承Animal类创建了一个新的类,实例化得到的对象obj,可以使用相同的方式使用obj.talk()
我们就可以不考虑类而统一用一种方式去使用对象,可以通过在父类引入抽象类的概念来硬性限制子类必须有某些方法名
import abc
# 指定metaclass属性将类设置为抽象类,抽象类本身只是用来约束子类的,不能被实例化
class Animal(metaclass=abc.ABCMeta):
@abc.abstractmethod # 该装饰器限制子类必须定义有一个名为talk的方法
def talk(self): # 抽象方法中无需实现具体的功能
pass
class Cat(Animal): # 但凡继承Animal的子类都必须遵循Animal规定的标准
def talk(self):
pass
cat=Cat() # 若子类中没有一个名为talk的方法则会抛出异常TypeError,无法实例化
但其实我们完全可以不依赖于继承,只需要制造出外观和行为相同对象,同样可以实现不考虑对象类型而使用对象,这正是Python崇尚的“鸭子类型”(duck typing):“如果看起来像、叫声像而且走起路来像鸭子,那么它就是鸭子”。比起继承的方式,鸭子类型在某种程度上实现了程序的松耦合
绑定方法和非绑定方法:
绑定方法:将调用者本身作为第一个参数自动传入,究竟是否绑定给对象还是类应该取决于函数体所操作或者需要的数据
1.绑定给对象的方法:调用者是对象,自动传入的是对象
2.绑定给类的方法:调用者是类,自动传入的是类
@classmethod装饰器绑定给类方法
非绑定方法:-》静态方法:没有绑定给任何人:调用者可以是类、对象,没有自动传参的效果
@staticmethod # 将下述函数装饰成一个静态方法
1.取绝对值:abs()
>>> abs(-1)
1
2.判断所有内容是否都为真,是则返回true,非0即为真:all()
>>> all([1,2,3])
True
>>> all([0,2,3])
False
3.判断至少有一个为真则返回true:any()
>>> any([0,0,1])
True
>>> any([0,0,0])
False
4.将十进制转化为二进制:bin(x)
>>> bin(255)
'0b11111111'
5.将十进制转化为八进制:oct()
>>> oct(10)
'0o12'
6.将十进制转化为十六进制:hex()
>>> hex(17)
'0x11'
7.判断真假:bool()
>>> bool(1)
True
>>> bool(0)
False
8.判断是否可以调用:callable()
>>> def func():
print('调用')
>>> callable(func)
True
注意函数不加括号
9.返回数字对应ASCII的字符:chr()
>>> chr(98)
'b'
>>> chr(25)
'x19'
>>> chr(108)
'l'
10.列出指定内容中所有可以调用的方法:dir()
>>> dir(help)
['__call__', '__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__']
11.一个数除以一个数,返回商和余数:divmod()
>>> divmod(5,2)
(2, 1)
12.filter(function,iterable):按照function的规则过滤iterable中的内容
注:这里的lambda表示一个匿名内部类,想要知道它的具体内容可以参照以前的文章。
>>> res=filter(lambda n:n<5,range(10))
>>> for i in res:
print(i)
0
1
2
3
4
13.字符串的版式,即利用特定的内容按顺序代替字符串中的{0}{1}:format
>>> name='ligang'
>>> age='25'
>>> print('{0}的名字是{1}'.format(name,age))
ligang的名字是25
14.将一个东西变成不可变得:frozen
>>> a=frozenset([1,4,5])
加了frozen之后,这个集合是不可以进行增删改的
15.将整个文件的内容都变成key:value的形式:globals()
>>> globals()
{'__name__': '__main__', '__doc__': None, '__package__': None, '__loader__': <class '_frozen_importlib.BuiltinImporter'>, '__spec__': None, '__annotations__': {}, '__builtins__': <module 'builtins' (built-in)>, 'func': <function func at 0x0000000002B79268>, 'res': <filter object at 0x0000000002AF6358>, 'i': 4, 'name': 'ligang', 'age': '25', 'a': frozenset({1, 4, 5}), 'b': {1, 5, 6}}
我们可以看到加粗的内容都是刚才用过的变量,都变成了key:value的形式
16.获取内存对应内容的对应的哈希值:hash()
>>> d='abc'
>>> hash(d)
6679396443929086459
17.给出对应函数的使用方法:help()
>>> help(abs)
Help on built-in function abs in module builtins:
abs(x, /)
Return the absolute value of the argument.
18.获取长度:len()
>>> a=[1,2,3]
>>> len(a)
3
19.判断一个东西是否为另一个东西:isinstance(a,b)
注意用之前要导入相应的包,才可以进行判断
20.一个数的多少次幂:pow()
>>> pow(3,3)
27
21.排序:sorted()
>>> sorted(a)
[1, 4, 5, 8, 25, 32, 36, 41, 66, 82]
22.求和:sum()
>>> a=[1,2,3,4,5,6,5,4,6]
>>> sum(a)
36
23.将两个列表合成一个一一对应的字典:zip()
>>> a=[1,2,3,4]
>>> b=['a','b','c','d']
>>> zip(a,b)
<zip object at 0x0000000002B7C608>
>>> c=zip(a,b)
>>> for i in c:
print(i)
(1, 'a')
(2, 'b')
(3, 'c')
(4, 'd')
返回的是一个生成器,必须调用for循环才能把它打印出来.