在Python中,函数可以访问模块变量,如下所示:
def pow(a):
return a**b
a = 3
b = 2
print(pow(a))
这被认为是不好的做法吗?
显而易见的替代方法是将所有参数显式传递给函数:
def pow(a, b):
return a**b
a = 3
b = 2
print(pow(a, b))
我使用第一种形式来限制传递给函数的参数数量,我想知道这是否被认为是不好的做法。
答案 0 :(得分:1)
最好将变量显式传递给函数。意图更清晰,功能的目的也是如此。请考虑以下事项:
my_list = [1, 2, 3]
min_len = 5
def check_length(my_list):
return len(my_list) < min_len
check_length(my_list)
乍一看,我看到check_length
被调用了,但它检查了多长时间?如果我不知道,我必须搜索它。这是一个麻烦,只会随着更大的脚本和功能而增长。
答案 1 :(得分:1)
这实际上取决于您的使用情况,因为:
import foo
import bar_var from bar as bvar
def myfun(a):
return foo.foo_func(a)
# foo is in module namespace, nobody adds it to the caller's signature
def myfun2(b):
myfun(b)
>>> myfun2(bvar) # returns foo.foo_func(bvar)
def outerfun(a):
def innerfun():
return a
return innerfun
>>> inner_alias = outerfun("foo")
>>> inner_alias()
"foo"
因此,请遵循以下最佳实践:使代码易于阅读和管理全局变量/命名空间,特别是记住可变数据结构将被修改,无论它们是否在签名中传递:
L = []
def foo(alist):
alist.append(1)
return alist
def foo2():
L.append(1)
return L
>>> foo(L)
[1]
>>> L
[1] #!!! (lists are mutable and python passes by assignment)
>>> foo2()
[1, 1]
>>> L
[1, 1]
P.S。在使用Python的OOP中,实例方法是使用实例作为第一个参数显式定义的(但是使用此参数自动隐式调用),将类名称空间暴露给方法:
class myClass(object):
def __init__(self): # the first argument must be the instance
# __init__ is the constructor which we are overriding here
self.inst_var1 = 1
# initialize an instance var
def add(self, i): # the first argument must be the instance
if i <= 0:
raise ValueError("i must be a positive number!")
# But ValueError is a module global, because Exceptions are in global namespace
return self.inst_var1 + i
>>> myclass_inst = myClass()
>>> myclass_inst.inst_var1
1
>>> myclass_inst.add(1)
# python automatically binds first argument to `myclass_inst`,
# as if myclass_inst.add = functools.partial(myclass_inst.add, myclass_inst)
2