Python 传递的参数的实际名称

Python 传递的参数的实际名称,python,parameters,Python,Parameters,是否可以在Python中获取所传递参数的名称 具体而言,我希望能够做到这一点: def a(name): print "the actual passed parameter is %s" %(???) 它解决了什么问题 所以,如果我需要在袋子和篮子里分发硬币,比如说袋子清单和篮子清单,我不需要发送一个明确的标识符,上面写着“袋子”或“篮子” 这就是我目前的工作方式。为此,我目前正在使用(全球)词典- ID = {'bag': bag_list, 'basket': basket_li

是否可以在Python中获取所传递参数的名称

具体而言,我希望能够做到这一点:

def a(name):
    print "the actual passed parameter is %s" %(???)
它解决了什么问题

所以,如果我需要在袋子和篮子里分发硬币,比如说袋子清单和篮子清单,我不需要发送一个明确的标识符,上面写着“袋子”或“篮子”

这就是我目前的工作方式。为此,我目前正在使用(全球)词典-

ID = {'bag': bag_list, 'basket': basket_list}

def a(name, id):
   dist_list = ID[id]
它还归结为将变量名转换为字符串,因为所需的行为也可以建模为:

def a(name):
    name = ???get variable name as string magically???
    if name.startswith('bag'): 
         dist_list = ID['bag']
    else:
         dist_list = ID['basket']
重新建模的问题在中得到了全面的回答,但我将重新发布这篇文章

  • 以防万一有一些修改,
  • 是否可以在其他脚本语言(如Perl或Tcl)中执行此操作
  • 更重要的是,如果两种建模方法不同,或者可以采用任何不同的方法

谢谢

这样的东西适合您的用例吗

>>> class Inventory(object):
    basket = 0
    bag = 0
    def add_coins(self, **kwargs):
        if 'bag' in kwargs:
            self.bag += kwargs['bag']
        if 'basket' in kwargs:
            self.basket += kwargs['basket']


>>> i = Inventory()
>>> i.add_coins(bag=6)
>>> i.bag
6
>>> i.add_coins(bag=2)
>>> i.bag
8
>>> i.basket
0

通常,您想要的是不可能的,因为Python不会传递附加名称的对象

在调用函数的情况下,如果用户总是使用关键字参数调用函数,则可以获得具有名称/值对的字典

所以你可以这样做:

然后用户必须调用函数,如下所示:

a(bag=3)
a(basket=5)
编辑:代码现在对于Python3.x是正确的,并且可以很容易地针对Python2.x进行修改(参见注释)

编辑:现在我想起来了,我们可以概括一下。我将把
ID
重命名为
\u容器

def a(**kwargs):
    for key, value in kwargs.items():
        if key in _containers:
            _containers[key].append(value)
        else:
            raise ValueError("invalid container name '%s'" % key)
现在,您可以通过一个调用附加多个容器。但这有点棘手,因为用户可能会执行以下操作:

a(bag=1, basket=2, bag=3)
bag=1
永远不会发生,因为
bag
将在字典中设置为
3
。(可能有一种棘手的方法可以用带有重载函数的自定义类来替换字典,但这种方法是疯狂的……我不建议编写那么棘手的代码。)

这并没有那么好,但是如果你想让名字以
bag
开头或者其他任何东西起作用,这就可以了:

def a(**kwargs):
    for key, value in kwargs.items():
        found = False
        for container_name in _containers:
            if key.startswith(container_name):
                _containers[container_name].append(value)
                found = True
                break
        if not found:
            raise ValueError("no container name matched '%s'" % key)

我认为你的问题在于争论的不同。有由调用方显式声明名称的关键字参数和简单的位置参数。你可以这样做

def a(**kwargs):
    if 'bag' in kwargs:
         dist_list = ID['bag']
    else:
        dist_list = ID['basket']
你必须像这样传递变量

a(bag=...)
或者,如果您想查看参数
是否与您可以执行的包或篮子一起启动

def a(**kwargs):
    if any(k.startswith('bag') for k in kwargs.iterkeys()):
        dist_list = ID['bag']
    elif any(k.startswith('basket') for k in kwargs.iterkeys()):
        dist_list = ID['basket']
    else:
        raise Exception('a requires argument starting with `basket` or `bag`')
但是你有一个问题,那就是确定哪把钥匙是从袋子还是篮子开始的,所以我可能会这样做

def a(**kwargs):
    valid_key = [k for k in kwargs.iterkeys() if k.startswith('bag') or k.startswith('basket')][0]
    if valid.key.startswith('bag'):
         dist_list = ID['bag']
    elif valid.key.startswith('basket'):
        dist_list = ID['basket']
    else:
        raise Exception('a requires argument starting with `basket` or `bag`')

这是可能的——但我认为这更像是一个肮脏的黑客行为。在阅读了我的解决方案后,如果你真的想走这条路,你应该后退一步,三思而后行

def a(name):
    global_variables = globals()
    try:
        name_of_passed_in_variable = [x for x in global_variables if id(global_variables[x]) == id(name)][0]
    except Exception:
        name_of_passed_in_variable = "unknown"
    print name_of_passed_in_variable, name

my_name = "Tom"
a(my_name)

a("Mike")

second_name = my_name
a(second_name)
将给出输出:

my_name Tom
unknown Mike
my_name Tom
通过我的例子,您还可以看到这种方法的缺点

  • 如果直接传入字符串而不指定变量,则无法确定名称
  • 如果对同一个变量有多个引用,则永远不知道将选取哪个名称

对于后一个问题,您当然可以实现一些逻辑来处理它,或者这对您来说根本不是问题。

我不确定我是否理解这个问题。如果您定义a(name)
参数的名称是
“name”
,不是吗?你还想叫什么名字?如果您是指用于调用函数的变量的名称,那么可能没有任何此类变量。如果我叫
a(“foo”)
,你知道有名字吗?a(foo+“bar”)怎么样?至于您想要的行为,为什么不直接将适当的列表传递给函数呢?我想让它根据我是传递bag_list还是basket_list进入正确的列表只是出于兴趣,您是否有理由使用
len(kwargs.keys())
而不是
len(kwargs)
。。。至少没有好的理由!我现在就编辑它,把它缩短。谢谢你指出这一点。>>>>test(dist_list=bag_list){'dist_list':bag_list}@ShyamSunder在我编辑我的答案后-你想达到这样的目的吗?是的,我想我可以直接做到:
code
a(bag_list=bag_list)
code
a(basket_list=basket_list)
my_name Tom
unknown Mike
my_name Tom