zoukankan      html  css  js  c++  java
  • 1. 如何将字符串常量转变为变量

    参考并转载:   https://mp.weixin.qq.com/s/-U0hKUvPBhFrhUdI0Ao3Og

    1. 如何动态生成变量名?

       

    已知 list = ['A', 'B', 'C', 'D'] , 
    如何才能得到以 list 中元素命名的新列表
    A = [], B = [], C = [], D = []呢?

    就是将字符串内容作为其他对象的变量名

    list 中的元素是字符串,此处的 ‘A’-‘D’ 是常量 ,而在要求的结果中,A-D 是变量 。

    如果强行直接将常量当做变量使用,它会报错:

     'A' = []
    ...SyntaxError: can't assign to literal

           报错中的literal 指的是字面量 ,这是计算机科学中常见的一个概念,用于表达源代码中的固定值。 例如,整数、浮点数、字符串等基本类型,就是字面量。

          字面量指的就是一个量本身,可以理解为一种原子性的实体,当然不能再被赋值了。

          所以,取出的字符串内容,并不能直接用作变量名,需要另想办法。

          有初学者可能会想,list[0] = [] 行不行?当然不行,因为没有出现 A 。那 A = list[0] ,接着 A = [] 呢?那也不行,因为这里的 A 是你凭空定义出来的,而不是从已有条件中生成的。

    2. 解决办法

    2.1   global()

    >>> list1 = ['A', 'B', 'C', 'D']
    >>> for i in list1:
    >>>     globals()[i] = []
    >>> A
    []

           这个方法通过修改全局命名空间,巧妙地“定义”出了新的变量。globals() 方法取出来的是一个字典,字符串 ‘A’ 是其中一个键值(key),而这个键值恰恰是全局命名空间中的一个变量,这就实现了从常量到变量的转化。

      在数据结构层面上,空列表 [] 作为一个值(value)跟它的字符串键值绑定在一起,而在运用层面上,它作为变量内容而跟变量名绑定在一起。

      看到这个回答的时候,我就突然想起来一篇文章,讲的正是动态地进行变量赋值 的问题啊!我似乎只关注了 globals() 与 locals() 用法的区别,却没有真正地掌握它们的原初用途。

    2.2   eval()动态执行代码的方法

    >>> list1 = ['A', 'B', 'C', 'D']
    >>> for i in list1:
    >>>     exec(f"{i} = []")
    >>> A
    []

      他的写法用到了 Python 3.6 才引入的 f-strings 特性,事实上,在较低版本中,也是可以实现的,只需要保证 exec() 方法接收的参数是包含了变量 i 的字符串即可,例如这样写:

    # 以下代码可替换上例的第 4 行
    exec(i + " = []")
    # 或者:
    exec("{} = []".format(i))
    # 或者:
    exec(' '.join([i, '= []']))

      这几种写法的区别只是字符串拼接法的区别,关于如何拼接字符串,以及不同方法间的区别,参看《Python拼接字符串的七种方式》。

      这个答案的核心在于 exec() 方法,它是内置的,用途是执行储存在字符串或文件中的代码段。

    它的基础用法如下:

    >>> exec('x = 1 + 2')
    >>> x
    3
    
    # 执行代码段
    >>> s = """
    >>> x = 10
    >>> y = 20
    >>> sum = x + y
    >>> print(sum)
    >>> """
    >>> exec(s)
    30

      看完了 exec() 的用法,我们再回来看 Q 同学的答案。for-循环中取出来的 i 是字符串,而拼接后的字符串经过 exec() 的处理,就获得了动态编写代码的效果。

      也就是说,因为字符串常量的内容被当做有效代码而执行了,其中的 'A'-'D' 元素,就取得了新的身份,变成了最终的 A-D 变量名。

      这个方法看起来很简单啊,可是 exec() 方法太生僻,直到 Q 同学提出,我们才醒悟过来。

    注意:在 Python3 中,exec() 是个内置方法;
    而在 Python2 中,exec 是个语句(statement),另外有个 execfile() 方法,两者相合并,
    就成了 Python3 中的 exec() 方法。
    本文使用的是 Python3。

    3 总结

    抽象一下最初的问题,

    它实际问的是“如何将字符串内容作为其它对象的变量名”,

    更进一步地讲是——“如何将常量转化为变量 ”。

    使用直接进行赋值的静态方法,行不通。

    两种方法都是间接的动态方法:

    一个是动态地进行变量赋值,通过修改命名空间而植入变量;

    一个是动态地执行代码,可以说是通过“走后门”的方式,安插了变量。

  • 相关阅读:
    Wamp 扩展Oracle Oci
    Yii 网站上线不需手动配置
    Centos 设置时区
    Crontab 入门
    centos apache安装oracle扩展
    Centos rpm 卸载
    mac vagrant 虚拟机nfs挂载点
    搭建php虚拟环境
    Mac 安装package control
    Sublime 安装、删除插件
  • 原文地址:https://www.cnblogs.com/jinfanfu/p/10732691.html
Copyright © 2011-2022 走看看