python对象和字典dict的相互转化【点.和[属性]】的访问区别及特殊方法名总结

为什么说在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"])

​

 

  • 0
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值