为什么说在python中一切都是对象:对象是Python对数据的抽象。Python程序中的所有数据都由对象或对象之间的关系表示。
对象的三个特征 1、身份 2、类型 3、值
但是在python的dict和对象在操作上区别很大【这点和JavaScript比区别很大】
正常情况来说【完全不做任何的处理】
python的dict只能采用obj["name"]的方式来写入和读取
python的对象只能采取obj.name 的方式来读取和写入
当然,python非常活跃,提供了一些特殊方法名来弥补这些问题:
比如可以把一个dict转换成obj的形式,也可以把一个obj转换成dict的形式
python 魔法方法补充(__setattr__,__getattr__,__getattribute__)总结参考:https://www.cnblogs.com/big-handsome-guy/p/8618078.html
【实战总结】object转换成dict[属性]访问的方式,重写【__getitem__和__setitem__方法】
'''
如果一个类的对象要兼容obj[属性访问],仅需要重写dict.__setitem__和dict.__getitem__方法即可
'''
class ObjectTest(object):
name = "kirin"
# # self.属性写入 等价于调用dict.__setitem__
__setitem__ = object.__setattr__
# # self.属性读取 等价于调用dict.__setitem__
__getitem__ = object.__getattribute__
# # 等价于__setitem__ = object.__setattr__
# def __setitem__(self, key, value):
# object.__setattr__(self, key, value)
#
# # 等价于__getitem__ = object.__getattribute__
# def __getitem__(self, item):
# return object.__getattribute__(self, item)
obj = ObjectTest()
obj["name"]="python"
print(obj["name"])
obj.name="python1"
print(obj.name)
【实战总结】dict转换成object【同时兼容.属性和[属性]访问】属性访问方式
参考别人案例:https://blog.csdn.net/u010870545/article/details/82771669
dd = {
"name": "18D_Block",
"xcc": {
"component": {
"core": [],
"platform": []
},
},
"uefi": {
"component": {
"core": [],
"platform": []
},
}
}
class Dict(dict):
# # self.属性写入 等价于调用dict.__setitem__
__setattr__ = dict.__setitem__
# # self.属性读取 等价于调用dict.__setitem__
__getattribute__ = dict.__getitem__
# # 等价于__setattr__ = dict.__setitem__
# def __setattr__(self, key, value):
# dict.__setitem__(self, key, value)
#
# # 等价于__getattribute__ = dict.__getitem__ 或 __getattr__ = dict.__getitem__
# def __getattribute__(self, item):
# return dict.__getitem__(self, item)
# 递归把dict转换成obj对象【兼容obj.属性和obj[属性]】
def dict_to_object(dictObj):
if not isinstance(dictObj, dict):
return dictObj
inst = Dict()
for k, v in dictObj.items():
inst[k] = dict_to_object(v)
return inst
obj = dict_to_object(dd)
print(obj["name"])
关于dict和object相互转换的原理分析【理论分析】:
'''
任何一个class类都会自带__setattr__和__getattribute__[__getattr__]方法【支持obj.属性访问】
如果一个类的对象要兼容obj[属性访问],仅需要重写dict.__setitem__和dict.__getitem__方法即可
'''
class ObjectTest(object):
name = "kirin"
age = 18
'''
class类对象自带__setattr__和__getattribute__[__getattr__]方法【支持obj.属性访问的原理分析】
'''
# obj.属性访问调用写入方法【self.name = "python"】
# 重写object.__setattr__方法
def __setattr__(self, name, value):
print("调用了__setattr__")
super().__setattr__(name, value)
# obj.属性访问调用读取方法self.name【建议读取优先访问此方法】
# 重写object.__getattribute__方法
def __getattribute__(self, item):
print("调用了__getattribute__")
return super().__getattribute__(item)
# getattr 拦截运算(obj.xx),对没有定义的属性名和实例,会用属性名作为字符串调用这个方法【不建议使用】
# 重写object.__getattr__方法
def __getattr__(self, item):
print("调用了__getattr__")
if item == 'age':
return 40
else:
raise AttributeError('没有这个属性')
'''
如果一个类的对象要兼容obj[属性访问],仅需要重写dict.__setitem__和dict.__getitem__方法即可
'''
# self[key]写入会调用此方法
# 这里是重写dict.__setitem__方法
def __setitem__(self, key, value):
print("调用了__setitem__")
super().__setattr__(key, value) # 等价于object.__setattr__(self, key, value) 内部使调用setattr()实现
# self[item]读取会调用此方法
# 这里是重写dict.__getitem__方法
def __getitem__(self, item):
print("调用了__getitem__")
return super().__getattribute__(item) # 等价于object.__setattr__(self, item) 内部使调用getattr()实现
dd = ObjectTest()
dd.name = "kirin"
print(dd.name)
dd["name"] = "kirin"
print(dd["name"])