Python高级知识点学习(二)
深入类和对象
鸭子类型
问:什么是鸭子类型?
答:当看到一只鸟走起路来像鸭子,游泳像鸭子,叫起来也像鸭子,那么这只鸟就可以被看做鸭子。(所有的类或对象,都实现了共同的方法,方法名要一样,这样的话这些类就归为一种类型,在调用时同时调用同样的方法)
在java中,要实现多态,所有子类必须继承父类并重写父类的方法;
在python中,python中对象和java不同,变量是动态的可以指向任何一个类型。
class Cat():
def say():
pass
class Dog():
def say():
pass
class Duck():
def say():
pass
三个类共同实现同一个方法且方法名相同,就实现了多态。
Python多态比Java简单正是因为python是动态语言。
抽象基类abc模块
何为抽象基类?
继续用java做比较,Python这里抽象基类可以当做java中的接口,java中是无法实现多继承的,java只能继承一个类,但是可以继承多个接口,接口是不能用来实例化的;所以Python里边抽象基类也是不能实例化的。
python是动态语言,动态语言是没有变量类型的,Python中变量只是个符号而已,它可以指向任何类型的对象。
所以在Python中也就不存在多态这种概念,我们可以赋值任何类型数据给Python中的变量,而且它是可以修改的,所以说它就不需要像java中一样去实现多态,因为本身从语言层面讲就是支持多态的语言。
动态语言和静态语言非常大的区别之一就是静态语言不需要我们指明变量类型,所以动态语言中也就少了编译时检查错误的环节,python中写错了代码只能在运行中发现错误。
不同魔法函数就赋予了类不同特性,和java非常大的区别就是不需要去继承某一个指定的类。
鸭子类型和魔法函数构成了Python语言的基础,也就是Python中的协议。
我们只需要去实现指定的魔法函数,类就可以是某种类型的对象,不同魔法函数具有的特性不同,这种使用魔法函数事先约定好的做法我们都可以称之为一种协议。
抽象基类用途:
- 我们在某些情况之下希望判定某个对象的类型
- 我们需要强制某个子类必须实现某些方法
抽象基类用法:
- 在基础类中,我们去设定好一些方法,所有继承这个基类的类都必须覆盖抽象基类的方法,
- 抽象基类是无法实例化的
- 所有的抽象基类继承的必须是metaclass=ABCMeta
在做框架编程时,往往我们需要使用框架者在使用类时必须实现类中的一些方法,这时候可以使用抽象基类,举了例子:
class CacheBase(metaclass=abc.ABCMeta):
@abc.abstractmethod
def get(self, key):
pass
@abc.abstractmethod
def set(self, key, value):
pass
class RedisCache(CacheBase):
pass
redis_cache = RedisCache()
运行结果:TypeError: Can't instantiate abstract class RedisCache with abstract methods get, set
在实例化RedisCache()这个时,就开始报错了,错误提示让我们必须实现get set方法。
补全这两个方法后运行就不报错了
class RedisCache(CacheBase):
def set(self, key, value):
pass
def get(self, key):
pass
redis_cache = RedisCache()
type和isinstance区别
尽量使用isinstance判断类型,避免使用type产生误差
is 和 == 符号 区别:
- is用法判断id是否相同
- ==用法判断值是否相等
类变量和实例变量(对象变量)
先看代码:
class A:
# 类变量
aa = 1
def __init__(self, x, y):
# self是类的实例
# 实例变量
self.x = x
self.y = y
# 上边赋值后 x y 都属于实例了 不再属于类了
a是实例 A是类 aa是类变量 类变量在所有实例中是共享的
a = A(2, 3)
A.aa = 11
a.aa = 100 # a实例新建一个属性 把aa放到a实例中 a.aa和A.aa是独立的
print(a.x, a.y, a.aa)
print(A.aa)
b = A(3, 5)
print(b.aa)
运行结果:
2 3 100
11
11
解释代码:
新建了一个名为A的类,类中新建类属性aa = 1
类中新建构造函数,绑定两个变量x y。
属性查找方式,向上查找,首先查找对象里有没有,再查找类中有没有
类变量和实例变量是独立的存在
- 类变量在所有实例中是共享的
- a.aa = 100:a实例新建一个属性 把aa放到a实例中 a.aa和A.aa是独立的。
建议以上代码反复测试加以记忆。
关注公众号
低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
-
上一篇
Python高级知识点学习(五)
dict的子类 首先,不建议自己编写代码继承dict和list这种原生使用c语言编写的,因为有时候,用c语言写的dict不会调用python写的覆盖的方法。 如果确实有继承dict来写代码的需求,可以使用UserDict,继承这个UserDict。 UserDict这个内部使用了python语言实现了c语言写的逻辑。 from collections import UserDict class Mydict(UserDict): def __setitem__(self, key, value): super().__setitem__(key, value*2) my_dict = Mydict(one=1) print (my_dict) 打印结果: {'one': 2} set和fronzenset set集合: 无序 不重复 set 接受一个可迭代对象 frozenset集合: 一旦设置好就无法修改。 frozenset为不可变类型。 相对于可变类型来说的好处,可以作为dict的key。 set的初始化方法: set([a, b, c]) a = {a, b, c} 两种都可以...
-
下一篇
Python高级知识点学习(三)
mro算法 类属性和实例属性的查找顺序 何为类属性:定义在类内部的的一些变量或者方法,都统称为类属性 何为实例属性:定义在对象内部的的一些变量或者方法,都统称为实例属性 对象也就是实例的意思。 class A: aa = 1 def __init__(self, x, y): self.x = x self.y = y a = A(2, 3) 类也是对象,看上边代码,实际上有两个空间,A 和 a 两个不同的空间。单继承时,属性查找方式,向上查找,首先查找对象里,再查找类中 在多继承时,会很复杂 python2.2之前,python里的类叫经典类,经典类继承方式如果不显式继承object,实际上是不会自动继承object,Python3中,经典类已经不存在了,都叫做新式类。经典类中,深度优先查找 。 Python2.3之后,广度优先也没有了,至今都采用C3算法Python3多重继承C3算法: #新式类 class D: pass class E: pass class C(E): pass class B(D): pass class A(B, C): pass print(A.__mr...
相关文章
文章评论
共有0条评论来说两句吧...


微信收款码
支付宝收款码