通过引用将值传递给python函数

时间:2014-05-17 22:34:08

标签: python function

我有allowed = ['someoption','someother']

default = 'default_value'

v来自用户输入。

然后当我这样做:

v = v if v.lower() in allowed else default,按预期工作,

v仅在allowed列表中列出的用户指定选项中取值,否则设置为default_value

但是,我希望通过定义验证来将验证分离为函数:

def validate(value, rules, default)
    value if value.lower() in rules else default

,但现在当我validate(v, allowed, default)时,尝试在allowed列表中输入值而不是,而不是让v按住default_value我得到了什么。

所以我希望将v作为参考传递并进行更改,但这并没有发生。我该怎么做才能得到预期的结果?

2 个答案:

答案 0 :(得分:2)

简单解决方案

首先,对validate函数的小修正:

def validate(value, rules, default)
    return value if value.lower() in rules else default

然后只需将值分配给结果

v = "something"
allowed = ["someoption", "someother"]
default = "default_value"
v = validate(v, allowed, default)

保持简单。

关于“通过引用传递” - Python没有这个概念。如果你传入一个函数不可变类型的值(比如一个字符串),它就会被称为“按值”。如果你传入可变对象(如列表),它就会被称为“通过引用”。没有办法,你会指示Python改变这样做的方式。

ugly_validate,其中“更改结果”

如果你真的坚持修改传入的结果,这种(丑陋的)方式可以起作用:

>>> def ugly_validate(value_lst, rules, default):
...     if value_lst[0].lower() not in rules:
...         value_lst[0] = default
...
>>> v = "something"
>>> allowed = ["someoption", "someother"]
>>> default = "default_value"
>>> v_lst = [v]
>>> ugly_validate(v_lst, allowed, default)
>>> v_lst
['default_value']
>>> v = "someoption"
>>> v_lst = [v]
>>> ugly_validate(v_lst, allowed, default)
>>> v_lst
['someoption']

使用允许值“身份字典”的替代解决方案

>>> allowed_dct = {key: key for key in allowed}
>>> allowed_dct
{'someoption': 'someoption', 'someother': 'someother'}
>>> res = allowed_dct.get(v, default)
>>> res
'someoption'
>>> v = "unknown"
>>> res = allowed_dct.get(v, default)
>>> res
'default_value'

使用专用类

>>> class AllowedValues():
...     def __init__(self, allowed_values, default):
...         self.allowed_values = allowed_values
...         self.default = default
...     def get(self, value):
...         if value.lower() in self.allowed_values:
...             return value
...         else:
...             return self.default
...
>>> allowed
['someoption', 'someother']
>>> judge = AllowedValues(allowed, default)
>>> v = "someoption"
>>> v = judge.get(v)
>>> v
'someoption'
>>> v = "unknonw"
>>> v = judge.get(v)
>>> v
'default_value'

答案 1 :(得分:1)

在Python中,所有内容都通过asssigment传递。在您的情况下,value名称被指定为v指向的同一对象,但只要您更改value,因为它指向的(字符串)是不可变的,它实际上是指向一个新的字符串对象,而不再指向v指向的对象。

执行您要执行的操作的最佳方式是validate函数返回新值(如果它不在rules中。

或者(但不推荐),如果您使v指向包含用户输入字符串的list,那么由于list s是可变的,因此更改为列表内部validate功能也将是"可见"在那个功能之外。