为了方便查阅,在此先放个链接全家桶。
突发奇想想要动态创建一系列对象,具体是这样的:
class Assign(object):
def __init__(self, h):
self.a = h + 10
self.b = h * 10
for i in range(10):
var_i = Assign(i)
其实很容易想到用个字典存储,创建dict_assign = {}
,对应的往里放往外取dict_assign['var' + str(i)]
,但是这写起来就非常的长,并且很不直观。经过查阅,发现有很多pythonic的办法:【转载】 Python动态生成变量、Python动态变量名定义与调用
一下相中用内置函数exec这个看上去特别简洁的方法,但是中间因为智商耽误很多时间。
工具要先用,再慢慢摸索怎么用,首先先看一下 Python3 exec 函数 和 Python format 格式化函数。
exec 执行储存在字符串的语句,因此我们只需要
for i in range(10):
exec('var_{} = {}'.format(i, i))
就可以动态创建一系列的变量,并赋值。
因此我的想法是:先创建对象、动态创建变量、将对象赋值给这个变量,实现起来是这样的:
class Assign(object):
def __init__(self, h):
self.a = h + 10
self.b = h * 10
for i in range(10):
exec('var_{} = {}'.format(i, Assign(i)))
然而!报了这样的错:
var_0 = <main.node object at 0x00000203A7F8F308>
^
SyntaxError: invalid syntax
在我困惑并查阅了很久的资料后,我突然醒悟:这是把对象的类型信息和内存信息返回来了,这样赋值就会报错。参考Python进阶-自定义类基础中:
这两个方法的区别在于,__repr__是给机器或者程序员看的字符串,而__str__是给用户看的字符串。一般遵循的原则是,__str__的结果就是用来给print函数输出的,而__repr__得到的字符串,有一部分甚至可以直接用eval函数让机器进一步执行(打基础的同学不建议用这种技巧)。
用print函数输出某个类实例时,会优先输出类__str__方法的返回值,如果没有就输出__repr__方法的返回值,如果没有自定义__repr__覆盖,那么原生的object.__repr__也直接输出该实例的类型信息和内存信息,比如刚才见过的<__main__.cat object at 0x00000207CB212668>。
作者:SyPy
链接:https://www.jianshu.com/p/232e55d7195d
来源:简书
简书著作权归作者所有,任何形式的转载都请联系作者获得授权并注明出处。
深究下去我还应该补一下基础知识:python 深入理解 赋值、引用、拷贝、作用域。
解决的办法很简单,就是对象也动态创建,实现起来是这样的:
class Assign(object):
def __init__(self, h):
self.a = h + 10
self.b = h * 10
for i in range(10):
exec('var_{} = Assign({})'.format(i, i))
Python中9种生成新对象的方法
Python中的eval()、exec()及其相关函数
exec在主函数中定义是没问题的,但是放到函数里就不能正常运行了,报错如下:
NameError: name ‘var_0’ is not defined
我们看这个对象的地址var_0 = <__main__.function.
,是个局部变量,详见cookbook大法好: 9.23 在局部变量域中执行代码。
为了修正这样的错误,你需要在调用 exec() 之前使用 locals() 函数来得到一个局部变量字典。
之后你就能从局部字典中获取修改过后的变量值了。
实际上对于 exec() 的正确使用是比较难的。大多数情况下当你要考虑使用 exec() 的时候,
还有另外更好的解决方案(比如装饰器、闭包、元类等等)。
看了大佬的建议我怒拍大腿!在此放上:9.8 将装饰器定义为类的一部分,以及我的笔记 【笔记2】python中@的用法。
【转载】 Python动态生成变量. https://www.cnblogs.com/dcb3688/p/4347688.html ↩︎
Python动态变量名定义与调用. https://www.cnblogs.com/technologylife/p/9211324.html ↩︎
Python3 exec 函数. https://www.runoob.com/python3/python3-func-exec.html ↩︎
Python format 格式化函数. https://www.runoob.com/python/att-string-format.html ↩︎
Python进阶-自定义类基础. https://www.jianshu.com/p/232e55d7195d ↩︎
python 深入理解 赋值、引用、拷贝、作用域. https://www.cnblogs.com/jiangzhaowei/p/5740913.html ↩︎
Python中9种生成新对象的方法. https://blog.csdn.net/xiemanr/article/details/77922917 ↩︎
Python中的eval()、exec()及其相关函数. https://www.cnblogs.com/yyds/p/6276746.html ↩︎
9.23 在局部变量域中执行代码. https://python3-cookbook.readthedocs.io/zh_CN/latest/c09/p23_executing_code_with_local_side_effects.html ↩︎
9.8 将装饰器定义为类的一部分. https://python3-cookbook.readthedocs.io/zh_CN/latest/c09/p08_define_decorators_as_part_of_class.html ↩︎
【笔记2】python中@的用法. https://blog.csdn.net/occamo/article/details/80842311 ↩︎