在函数内部动态创建变量

时间:2020-03-06 14:35:16  来源:igfitidea点击:

我想从字典中的函数内部创建变量。

可以说我有一本字典

bar = {'a': 1, 'b': 2, 'c': 3}

和功能

def foo():
  pass

我想要做的是创建内部函数" foo"变量,每个字典项名称的名称和值作为字典项值

所以最后应该类似于

def foo():
  a = 1
  b = 2
  c = 3

有可能吗?如果确实如此,该怎么做?

解决方案

你为什么要做这样的事情?除非我们实际上对函数内部的变量进行任何操作,否则仅分配几个变量然后将其丢弃的函数与def foo()不能区分开:pass(优化器在生成完全相同的字节码时是合理的)。

如果我们还想动态添加使用值的代码,则可以使用exec来做到这一点(尽管除非这确实是用户输入的代码,否则几乎肯定会有更好的方法来执行所需的操作)。例如:

some_code = '  return a+b+c'
exec "def foo():\n  " + '\n  '.join('%s = %s' for k,v in bar.items()) + '\n' + some_code

(请注意,代码必须缩进相同的级别。)

另一方面,如果我们想将这些值实际分配给函数对象(因此我们可以执行foo.a并得到1个示例代码没有执行的注释),则可以通过以下方式执行此操作

for key, val in bar.items():
    setattr(foo, key, val)

问题不清楚。

如果要在不运行foo时"设置"所述变量,则不能,不能。还没有框架对象可用于"设置"局部变量。

如果要在函数主体中执行此操作,则不应该这样做(请查看python文档中的locals())。

但是,我们可以执行foo .__ dict __。update(bar),然后甚至可以从函数内部访问这些变量,如foo.a,foo.b和foo.c。问题是:为什么要这样做?为什么一门课不适合目的?

谢谢大家,我明白了。我不应该这样做。但是,如果古玩是我想做的,就是在Django的view函数中以某种方式缩短行数。我有很多字段的表单,而不是接收以下形式的每个字段:

first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name'] ..

我正在考虑采用我的表单类的每个属性名称并对其进行循环。像这样:

for name in ProfileRegistration.base_fields.__dict__['keyOrder']:
   # and here the variables that i tried to assign

根据评论,也许我们真正想要的是类似束对象的东西:

class Bunch(object):
    def __init__(self, **kwargs):
        self.__dict__.update(kwargs)

b=Bunch(**form.cleaned_data)

print b.first_name, b.last_name

(**语法是因为在情况下不使用Bunch类型的对象,就像Bunch(foo = 12,bar ='blah')一样,但为了与正常用法保持一致,我将其保留了)

这确实需要" b"。前缀来访问变量,但是如果我们考虑一下,这并不是一件坏事。请考虑一下,如果有人设计了一个POST请求来覆盖我们不希望被覆盖的变量,那么它将很容易产生崩溃和DOS攻击,并且很容易引入更严重的安全漏洞。