技术背景

当我们在Python中写一个class时,如果有一部分的成员变量需要用一个字典来命名和赋值,此时应该如何操作呢?这个场景最常见于从一个文件(比如json、npz之类的文件)中读取字典变量到内存当中,再赋值给一个类的成员变量,或者已经生成的实例变量。

使用__dict__定义成员变量

在python中直接支持了__dict__.update()这样的方法来操作,避免了对locals()、vars()和eval()函数的使用,我们可以直接看这样的一个案例:

In [1]: dict_a = {'a':1, 'b':2}

In [2]: dict_b = {'c':3}

In [3]: class D(object):
...: def __init__(self):
...: self.d = 4
...: self.__dict__.update(dict_a)
...: self.__dict__.update(dict_b)
...: In [4]: new_D = D() In [5]: new_D.__dict__
Out[5]: {'d': 4, 'a': 1, 'b': 2, 'c': 3} In [6]: new_D.a
Out[6]: 1 In [7]: new_D.c
Out[7]: 3

在这个案例中,我们在类的外部定义了两个字典dict_adict_b,字典的key值都是字符串的格式。而我们知道字符串格式在python中如果不使用eval,是不能直接作为变量名来使用的。而通过__dict__.update()的方法将字典导入后,会自动识别其中所有的key和value值,转而赋值给当前类作为成员变量。但是这个方法有一个缺点是,只能通过单层的字典来赋值,如果遇到有层级结构的字典,是不会自动分辨层级结构进行赋值的,比如下方的代码:

In [15]: dict_a = {'f':{'h':8},'g':7}

In [16]: new_D = D()

In [17]: new_D.__dict__
Out[17]: {'d': 4, 'f': {'h': 8}, 'g': 7, 'c': 3}

嵌套字典转成员变量

根据上一个章节中最后提到的这个特殊场景,我们需要对字典内的元素进行递归,如果遇到嵌套的字典元素,则递归的将该元素添加到下一层级的成员变量中,具体代码如下所示:

dict_a = {'f':{'h':8},'g':7}
dict_b = {'c':3} class D:
def __init__(self, *args):
for arg in args:
for k, v in arg.items():
if isinstance(v, dict):
self.__dict__[k] = D(v)
else:
self.__dict__[k] = v new_D = D(dict_a, dict_b)
print (new_D.__dict__)
print (new_D.f.h)

最终的输出结果如下所示:

{'f': <__main__.D object at 0x7fd2f32a4340>
, 'g': 7, 'c': 3}
8

可以看到,我们最终通过new_D.f.h的方法,成功读取了原有的嵌套字典中的value。虽然这种写法看起来不是很优雅,但是似乎也没有更好的解决方案。并且,通过这个小问题的实践,发现了另外一个略有意思的问题:对python中的字典类型进行更新时,如果key的字符串中带有点号,比如parDict['group1.b'] = 3,只能通过这样的字符串的形式进行更新,如果使用parDict.update(group1.b=4)则会发生报错,这是因为点号在python中不是一个标识符,不能用于命名,原文内容如下:

The valid characters for identifiers are the same as in Python 2.x: the uppercase and lowercase letters A through Z, the underscore _ and, except for the first character, the digits 0 through 9.

总结概要

本文所解决的问题场景是这样的:如果给定一个字典,比如一般从json文件或者npz文件中加载出来的数据都是字典的数据结构,如果我们希望把这个字典赋值给一个类,且使得字典的key和value分别作为类的成员变量名和成员变量值,那么该如何实现呢?对于一个展平的字典而言(没有嵌套字典),我们直接使用update就可以将字典中的所有key和value转变为当前类的成员变量。比较麻烦的是包含有嵌套字典的层级结构字典,此时我们只能使用循环,并且递归的对类的成员变量进行赋值。

版权声明

本文首发链接为:https://www.cnblogs.com/dechinphy/p/dict-class.html

作者ID:DechinPhy

更多原著文章请参考:https://www.cnblogs.com/dechinphy/

打赏专用链接:https://www.cnblogs.com/dechinphy/gallery/image/379634.html

腾讯云专栏同步:https://cloud.tencent.com/developer/column/91958

参考链接

  1. https://blog.csdn.net/csrh131/article/details/100138474
  2. https://stackoverflow.com/questions/67662925/dictionary-keys-with-a-dot-does-not-work-with-update

Python中将字典转为成员变量的更多相关文章

  1. python中将函数赋值给变量时需要注意的一些问题

    python中将函数赋值给变量时需要注意的一些问题 变量赋值是我们在日常开发中经常会遇到的一个问题,本文主要给大家介绍的是关于python将函数赋值给变量时需要注意的一些问题,分享出来供大家参考学习, ...

  2. python 私有和保护成员变量如何实现?—— "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量;" 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据

    默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量.在python中定义私有变量只需要在变量 ...

  3. python 实例化 类方法 静态方法 成员变量 实例方法 等调用

    1.参考代码如下 # coding:utf-8 class student: # 成员变量 ok = None like = '八戒你瘦了' # 实例方法 def __init__(self): # ...

  4. Python的类变量和成员变量、类静态方法和类成员方法

    先说明几个相关的术语:attribute.function.method. attribute:类对象的数据成员.我们经常会在Python代码出错时遇到:“AttributeError: 'My_Cl ...

  5. python中将字典形式的数据循环插入Excel

    1.我们看到字典形式的数据如下所示 list=[["2891-1", "D"],["2892-1", "D"],[&qu ...

  6. Python中将字典转换为有序列表、无序列表的方法

    说明:列表不可以转换为字典 1.转换后的列表为无序列表 a = {'a' : 1, 'b': 2, 'c' : 3} #字典中的key转换为列表 key_value = list(a.keys()) ...

  7. 福利->KVC+Runtime获取类/对象的属性/成员变量/方法/协议并实现字典转模型

    我们知道,KVC+Runtime可以做非常多的事情.有了这个,我们可以实现很多的效果. 这里来个福利,利用KVC+Runtime获取类/对象的所有成员变量.属性.方法及协议: 并利用它来实现字典转模型 ...

  8. Python 类变量和成员变量

    Python 类变量和成员变量 类与对象的方法 我们已经讨论了类与对象的功能部分,现在我们来看一下它的数据部分.事实上,它们只是与类和对象的名称空间 绑定 的普通变量,即这些名称只在这些类与对象的前提 ...

  9. python中类变量和成员变量、局部变量总结

    class Member(): num= #类变量,可以直接用类调用,或用实例对象调用 def __init__(self,x,y): self.x=x #实例变量(成员变量),需要它是在类的构造函数 ...

随机推荐

  1. Redis持久化、主从与哨兵架构详解

    目录 Redis持久化 RDB快照(snapshot) AOF(append-only file) AOF重写 Redis 4.0 混合持久化 Redis数据备份策略: Redis主从架构 Redis ...

  2. CobaltStrike逆向学习系列(1):CS 登陆通信流程分析

    这是[信安成长计划]的第 1 篇文章 关注微信公众号[信安成长计划][SecSource] 0x00 目录 0x01 密码校验 0x02 aggressor.authenticate 0x03 agg ...

  3. jmeter实现sha256算法加密

    方法一:自带函数 参数含义 算法摘要:MD2.MD5.SHA-1.SHA-224.SHA-256.SHA-384.SHA-512 String to be hashed:要计算的字符串: Salt t ...

  4. 五分钟,手撸一个Spring容器!

    大家好,我是老三,Spring是我们最常用的开源框架,经过多年发展,Spring已经发展成枝繁叶茂的大树,让我们难以窥其全貌. 这节,我们回归Spring的本质,五分钟手撸一个Spring容器,揭开S ...

  5. 善用商业智能BI系统,让数据分析更智能

    数据分析,是一种基于系统化分析问题的方式,是一种手段,也可以是一种工具,可以很简单也可以很复杂.它可以用在各个场景,比如现在的B2C\B2B--等等. 简单点的例子:通过分析购买产品的人大多都来自于北 ...

  6. Weblogic补丁升级常见问题

    转至:https://blog.csdn.net/weixin_44659716/article/details/106804177 常用企业级版本:Weblogic 11g(weblogic10.3 ...

  7. 走进第四范式:决策类AI企业的生存之道

    根据不同的应用领域,人工智能行业可以分为视觉类人工智能.语音及语义类人工智能和决策类人工智能. 通常,我们接触的都是视觉类.语音类的人工智能,它们主要用来帮助人类执行具体任务,例如人脸识别,语音控制等 ...

  8. VSCode空格变成虚点

    "editor.renderWhitespace": "all",

  9. 使用Dapper访问SQL Server数据库

    对应Demo程序名:DapperDemo 准备工作:为项目安装Dapper类库 方法一:项目中添加:项目名右键:Manage NuGet Packages:搜索Dappe:点击安装 方法二:在NuGe ...

  10. 微服务从代码到k8s部署应有尽有大结局(k8s部署)

    我们用一个系列来讲解从需求到上线.从代码到k8s部署.从日志到监控等各个方面的微服务完整实践. 整个项目使用了go-zero开发的微服务,基本包含了go-zero以及相关go-zero作者开发的一些中 ...