本篇内容介绍了“Python中__dict__有什么用”的有关知识,在实际案例的操作过程中,不少人都会遇到这样的困境,接下来就让小编带领大家学习一下如何处理这些情况吧!希望大家仔细阅读,能够学有所成!
网站建设哪家好,找创新互联建站!专注于网页设计、网站建设、微信开发、微信小程序定制开发、集团企业网站建设等服务项目。为回馈新老客户创新互联还提供了双柏免费建站欢迎大家使用!
Python这门编程语言的最大的好处就是其语言的动态性带来编程的便利性,不像静态语言那样死板,比如它可以运行期动态添加类定义时没有的属性,例如:
class A: def __init__(self): self.name = 'zhang' def eat(self): print('eat') a = A() a.age = 10 print(a.age)
在Java中这段代码可定是没法通过编译的,但在Python中这样的操作不再是司空见惯的事情,那Python解释器在背后究竟做了什么操作呢?答案是__dict__
,Python中的所有内建(build-in)数据类型(type)都有属性__dcit__
,当然自定义的类(class)也有,因为自定义的类也是一种数据类型嘛。在a.age=10
前后分别加上一行print a.__dict__
可以得到结果:
{'name': 'zhang'} {'age': 10, 'name': 'zhang'} 10
不难看出,在运行期和类定义期所定义的实例对象属性放在该对象的 __dict__
属性中,接下来在a=A()
后面加上几行代码:
A.country = "China" print a.country print a.__dict__
得到结果:
China {'age': 10, 'name': 'zhang'}
对象a的__dict__
属性中并没'country'这个属性,那它是哪来的呢?那么不妨打印类对象A的__dict__
看看:
print a.country print a.__dict__ print A.__dict__
输出结果:
China {'age': 10, 'name': 'zhang'} {'country': 'China', '__module__': '__main__', 'eat':, ...省略}
这下应该明白了,在运行期间,定义的实例对象(a)的属性是放在a.__dict__
中,而定义的类对象(A)的属性是放在A.__dict__
中,那为什么实例对象a是怎么访问到country属性的呢? Python中是这样约定的,以obj.attr访问时,它会按照如下顺序去查找:
对象自身,obj.__dict__['attr']
对象类型,obj.__class__.__dict__['attr']
对象类型的基类,obj.__class__.__bases__中的所有__dict__['attr']
。注意,当多重继承的情况下有菱形继承的时候,Python会根据MRO确定的顺序进行搜索。
如果在基类都还没找到要访问的属性时,Python解释器就会跑出一个异常:AttributeError。那么问题来了,我们是否可以给内建(build-in)类型添加一些自定义的属性呢?比如:
list.myExtension = lambda self,x:x * 2 list.myExtension(10)
运行的时候,解释器会报错:TypeError: can't set attributes of built-in/extension type 'list',那能否向list的__dict__
属性中添加一个值呢?
list.__dict__['myExtension'] = lambda self, x:x * 2
还是一样,没法运行:TypeError: 'dictproxy' object does not support item assignment,细细思来,后者不能运行也是符合情理的,两者就是等价的东西,那为什么不允许程序员扩展内建类型呢?
后面那位睡觉的同学你来回答一下,答曰:Guido van Rossum老爹是用C语言来实现的这些类型,你是没法再修改的,那如何优雅地扩展已有类型呢?知道OOP的同学都会用继承的方式来做。于是那位同学继续睡觉去了。
“Python中__dict__有什么用”的内容就介绍到这里了,感谢大家的阅读。如果想了解更多行业相关的知识可以关注创新互联网站,小编将为大家输出更多高质量的实用文章!