Python:将参数转换为dict,如PHP';它很紧凑吗?

Python:将参数转换为dict,如PHP';它很紧凑吗?,php,python,reflection,syntax,Php,Python,Reflection,Syntax,我想要一个与PHP函数完全相同的函数 >>> dict( var1=1, var2='a', var3=1+3j ) {'var1': 1, 'var3': (1+3j), 'var2': 'a'} i、 例如,如果我传入一个变量名列表: compact('var1','var2') 它还给了我一个命令: {'var1':var1, 'var2':var2} 调用方中使用的变量名对被调用函数不易使用。也许可以高级使用inspect,但最好重新思考为什么需要变量名 更新:现

我想要一个与PHP函数完全相同的函数

>>> dict( var1=1, var2='a', var3=1+3j )
{'var1': 1, 'var3': (1+3j), 'var2': 'a'}
i、 例如,如果我传入一个变量名列表:

compact('var1','var2')
它还给了我一个命令:

{'var1':var1, 'var2':var2}

调用方中使用的变量名对被调用函数不易使用。也许可以高级使用
inspect
,但最好重新思考为什么需要变量名

更新:现在我知道你真正需要的是什么(“我想把我的变量传递给我的模板”),答案很简单:使用
locals()
:它返回一个字典,将你所有的局部变量名映射到它们的值

更新2:这个怎么样

def only(d, *keys):
    """Return the subset of dict `d` whose keys are in `keys`."""
    return dict((k,v) for k,v in d.iteritems() if k in keys)

...

a = 17
b = 23
template_data = only(locals(), "a", "b")

函数看不到其实际参数的名称(如果有!-),事实上也没有任何迹象表明这些实际参数是表达式的结果,而这些表达式恰好是单个变量,而不是常量、函数调用或任何类型的其他表达式

因此,您所需要的,正如您所指定的,是完全不可行的。

如果您有一个名为args的列表,并且希望将其放入一个名为kwargs的字典中,如您的示例所示:

for k,v in enumerate(args):
    kwargs["var%d"%(k+1)] = v
但是,这些键实际上是args中项目的索引;这不会有用吗?

(1)Python不是PHP。(2) “传入函数时变量名丢失”为true

不要为此使用变量

做些更简单的事。使用
dict
功能

>>> dict( var1=1, var2='a', var3=1+3j )
{'var1': 1, 'var3': (1+3j), 'var2': 'a'}
这似乎是你想要的。变量“names”在那里正好一次
您实际上不需要创建其他本地临时变量。

这很尴尬,而且有限制,但对于其他变量,它可以工作

def p(*args):
  p = {}
  for i in args:   
     exec 'p["%s"] = %s' % (i, i)
  return p
在的帮助下,您可以使用
decorator
解决方案,以便将其应用于任何函数:

def compactor(func):
    import inspect
    def compactor_impl(*args, **kwargs):
        arg_names = inspect.getargspec(func)[0]
        return dict(zip(arg_names, args))
    return compactor_impl

@compactor
def package(var1, var2, var3):
    pass

@compactor
def package2(var1, var2, var3, supervar):
    pass

assert package(1, 2, 3) == {'var1': 1, 'var2': 2, 'var3': 3,}
assert package2(1, 2, 3, 'boh') == {'var1': 1, 'var2': 2, 'var3': 3, 'var3': 3, 'supervar': 'boh'}
我假设这些函数除了返回
名称值
对之外什么都不做。您可能需要添加一些检查(断言),以确保
len(args)==len(arg_name)
,并且
kwargs
为空,因为一旦应用了装饰器,就不会检查该值。

只需在函数开头使用locals()

def foo(x,y): 
   print x,y

def jar(x,y):
   foo(**locals())

def varjar(x,y):
   print locals()
   args =  locals().copy()
   args['x'] += 1
   args['y'] += 2
   foo(**args)
  • foo(1,2)和jar(1,2)打印12
  • varjar(1,2)打印{'y':2,'x':1}和2 4

这个问题可能会有所帮助:您希望表达式结果参数的“变量名”是什么?@Will:您是对的。我没想清楚。更新的问题。我想它是
compact('var1','var2')
;如果我将变量的名称作为字符串而不是实际值传递,会怎么样?有没有一种方法可以检索这些值?据我所知(有一点),python会动态地进行编译/检查。在这种情况下,将有一个数据结构保存这些变量的名称和/或值,并将其缩减为值,是否可能得到该值?或者,在程序开始执行之前,它会被缩减为值。@咕噜,Python可以很好地从现有编译的字节码文件(
.pyc
扩展名)运行代码——如果不存在,它会创建它(或者如果需要的话,只在内存中获取字节码),之后不会保留不必要的元信息。@Mark,如果没有深层的“黑魔法”内省(对调用方的框架及其局部和全局进行内省),就不应该在生产代码中使用。为什么不接受Python的“显式优于隐式”口号,只需调用
f(var1=var1,var2=var2)
?当然,值不必与名称相同,但没有任何东西禁止它们相同。现在这变得很简单,它只是
def(**k):返回k
!-)(或f=dict;-)。我看到你的评论说这“违背了目标”,但关键是你的目标不可能在没有不必要的复杂情况下实现@亚历克斯:我想我有不同的信仰。我不认为我应该在可以推断的地方键入任何内容。我相信传统胜过配置。智能默认值,您可以在必要时覆盖,但不必到处覆盖。这与目的背道而驰。我试图避免写
dict(var1=var1)
{var1':var1}
@S.Lott,你能读一下我在@Alex Martelli的回答中问的问题吗。如果变量名丢失,那么必须有某种机制为任何变量名提供值?我有什么误解吗。我还假设在python中编译/执行是不可复制的。@Gollum:我不知道当对变量求值时,对象(而不是变量)在函数求值过程中会“丢失”什么。什么是“丢失”?对变量求值以查找对象,该对象将在计算的整个生命周期内保持不变。对象将一直存在,直到没有对它的引用为止。“丢失了什么?”你在说什么?@s.Lott,谢谢你的时间。阅读Alex Martelli给出的答案。我指的是元信息。比如变量名-->value@Gollum:该值独立于所有变量名而存在。我不知道这是怎么回事,甚至不知道问题是什么。Alex回答中的讨论很难理解,因为每个人都在谈论变量和对象之间的一些完全神奇和毫无意义的联系。我没有及时得到这个cry**y解决方案,OPer发布了一些基本相同的更好的东西!:/这比我在我的问题(更新)中发布的内容更不安全,并且有相同的问题。事实上,我注意到:)(事实上,你的问题更好,但也有相同的问题;但我在看到更新之前已经让alrady写过了)嗯?我的变量实际上不会这样命名我想要变量名,因为我需要将它们传递到我的模板中。这将用于Django项目,我已经厌倦了编写
{'var':var}
。如果有一个模式,它可以被编码和简化。啊哈!真正的需要是一个非常简单和通灵的答案,添加在上面。@Ned: