请选择 进入手机版|继续访问电脑版
发新帖

如何在类中将字符串转换成变量名?

[复制链接]
6986 38
dwjgwsm  新手上路  发表于 2018-4-3 14:36:43 | 显示全部楼层
@wwqgtxx x 所指代的字符串就是未知的,看来就是没有别的更好的办法了

举报 使用道具

回复
dwjgwsm  新手上路  发表于 2018-4-3 14:38:29 | 显示全部楼层
一个更恰当的例子:

import numpy as np
class aa:
    def run(self,dict0):
        for k, v in dict0.items():
            exec(k + "=v")
        #############
        print(x1)

if __name__ == '__main__':
    dict0 = {'x1': np.arange(5), 'y1': np.arange(5) * 2}
    r = aa()
    r.run(dict0)
    for key,value in dict0.items():
        exec(key+"=value")
    print('-------')
    print(x1) #这个在类之外使用就没问题

举报 使用道具

回复
dwjgwsm  新手上路  发表于 2018-4-3 14:40:58 | 显示全部楼层
@wwqgtxx 不管你取什么名字,这的确不重要, 但你在后面的代码中引用这个变量的时候你都得前面加个 locals()前缀啊

举报 使用道具

回复
wwqgtxx  新手上路  发表于 2018-4-3 14:42:21 | 显示全部楼层
@dwjgwsm 你这种在任何一个 IDE 中都会报错的用法自己看着不觉得扎眼么,至于 python 的设计者为什么这么做的原因很简单,你对一个函数内的局部命名作用域的修改并没有什么意义,出了函数不还是被销毁了
比如你上面的例子和你
dict0 = {'x1': np.arange(5), 'y1': np.arange(5) * 2}
print(dict0['x1'])
这样写有什么本质上的区别么

举报 使用道具

回复
wwqgtxx  新手上路  发表于 2018-4-3 14:42:44 | 显示全部楼层
问题是你后面为什么要用一个动态的变量名,在一个函数的内部
x='abcd'
locals()['v']=np.arange(5)
v=np.arange(5)
exec(x+"=v")
print(abcd)
这种代码和
v=np.arange(5)
x = v
printf(x)
这两种代码你能告诉我有什么区别么

举报 使用道具

回复
wwqgtxx  新手上路  发表于 2018-4-3 14:47:33 | 显示全部楼层
说到底,你在模块级别可以那样写只是因为你这样的操作把 x1 这个变量定义成了一个全局变量了,他从这个模块外部是可以被访问的
而你在一个函数内部声明了一个叫 x1 的变量和声明了一个叫 x2 的变量有什么区别,他都是指向一块栈内存而已,出了这个函数谁也访问不到他,那么他的名字有出了给你看着舒服还有什么意义
如果你用过 C/C++这种语言就知道了,变量的名字根本就不会被保存下来,编译期间就被擦除了,运行时完全没人知道他叫什么名字

举报 使用道具

回复
dwjgwsm  新手上路  发表于 2018-4-3 14:52:34 | 显示全部楼层
@wwqgtxx 21 楼的代码简单表示了我想在 aa.run 中批量生成一批局部变量.  实际上我的代码逻辑还不是这样的,实际的逻辑是,类 aa 继承了一个基类,基类隐藏了很多复杂的功能实现,aa.run 每隔几秒钟运行一次,每一次运行完毕,会将 run 中的很多局部变量集中保存到基类中的一个字典变量中,下一次运行时,首先恢复这些局部变量.不知道你明白我的意思了吗

举报 使用道具

回复
dwjgwsm  新手上路  发表于 2018-4-3 14:52:52 | 显示全部楼层
而且 aa.run 由于运算量大,还采用了多进程

举报 使用道具

回复
wwqgtxx  新手上路  发表于 2018-4-3 14:53:40 | 显示全部楼层
@dwjgwsm “会将 run 中的很多局部变量集中保存到基类中的一个字典变量中”,你就不能直接在基类的字典变量中直接操作么,还要“下一次运行时,首先恢复这些局部变量”不觉得很多余么,如果你说你就是不想每次都调用 xxx_dict['aaa']这种非要用 aaa 这种形式调用,我只能告诉你没有办法 python 不支持引用别名这种操作,你可以去用 C++去,python 中无论如何都不可能实现这样的操作
在你的上一个问题 /t/439895 中,@chenstack 已经告诉你了,python 的 locals()是不可更改的,你觉得他能修改那是因为他只是一份复制,并不是真正的局部命名域,换句话说不可能动态批量生成一批局部变量

举报 使用道具

回复
wwqgtxx  新手上路  发表于 2018-4-3 14:54:55 | 显示全部楼层
另外你提到了多进程,那么很遗憾的告诉你,如果你想用一个共同基类来在多进程中共享数据,那么你可以试试看,他们之间的数据根本就不会保持同步,你要是说多线程那还可以理解,否则你就需要进行进程间通讯来交换数据

举报 使用道具

回复
dwjgwsm  新手上路  发表于 2018-4-3 14:56:43 | 显示全部楼层
@wwqgtxx 恩,非常感谢!反正我的想法是无法实现的了,我还是老老实实用 locals()['abcd']吧,就是代码看着太难看了

举报 使用道具

回复
wwqgtxx  新手上路  发表于 2018-4-3 14:56:49 | 显示全部楼层
如果你怕多线程同时修改基类数据的问题,你需要的是加锁,而不是用这种蹊跷意淫
在函数的开头把基类的 dict 给 copy 一份,在函数结尾再 update 回去,当然记得在 copy 和 update 的时候加锁,要不然会出现很多意想不到的问题

举报 使用道具

回复
dwjgwsm  新手上路  发表于 2018-4-3 15:03:16 | 显示全部楼层
@wwqgtxx 这个你不用担心,我用 Manager 把它传走了

举报 使用道具

回复
wwqgtxx  新手上路  发表于 2018-4-3 15:03:47 | 显示全部楼层
另外一点,能不要用 locals()就不要用,你自己创建一个 dict 不好么,locals()存在的目的只是为了用来读取的,任何修改 locals()的行为都是未定义的,也就是说天知道会在什么环境什么版本就就会崩掉

举报 使用道具

回复
dwjgwsm  新手上路  发表于 2018-4-3 15:11:58 | 显示全部楼层
run 里面的代码是会经常改变的(写各种交易策略的),如果将来真的崩了我就只有坚守老版本了

举报 使用道具

回复
wwqgtxx  新手上路  发表于 2018-4-3 15:21:16 | 显示全部楼层
@dwjgwsm 你自己用一个 dict 来进行操作不好么,总是用 locals()和 exec()这种函数天知道时候会出错

举报 使用道具

回复
dwjgwsm  新手上路  发表于 2018-4-3 15:23:03 | 显示全部楼层
@wwqgtxx 也可以,  反正我的想法也无法实现,  c=(a>b) & (a>locals()['abcd'])  和  c=(a>b) & (a>dict0['abcd'])   谁也不比谁好看

举报 使用道具

回复
wwqgtxx  新手上路  发表于 2018-4-3 15:25:33 | 显示全部楼层
@dwjgwsm 还有个办法,用一个 data 类来存储
class DefaultNamespace(object):
    def __init__(self, default_value=None):
        super(DefaultNamespace, self).__setattr__("_default_value", default_value)

    def __getattribute__(self, item):
        try:
            return super(DefaultNamespace, self).__getattribute__(item)
        except AttributeError:
            pass
        except KeyError:
            pass
        return super(DefaultNamespace, self).__getattribute__("_default_value")

    def __getstate__(self):
        return self.__dict__

然后你在函数开头来 data = DefaultNamespase()
后面就直接用 data.abcd = xxxx 还有 if(data.abcd > xxx) 这种就行了,看着也相对舒服一点

举报 使用道具

回复
dwjgwsm  新手上路  发表于 2018-4-3 15:28:25 | 显示全部楼层
@wwqgtxx 好的,非常非常感谢!

举报 使用道具

回复
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

快速回复 返回顶部 返回列表