【问题标题】:Can I reference or reuse a Python function parameter for other function parameters?我可以为其他函数参数引用或重用 Python 函数参数吗?
【发布时间】:2018-03-08 14:18:57
【问题描述】:

我正在创建一个函数,将一个或两个形状列表 A = [x1,y1,c1] / B = [x2,y2,c2] 作为输入。如果同时提供了形状 A 和 B,则每个都在 A 和 B 的一个地方使用。如果只提供一个形状 (A),则默认情况下,该函数会在两个不同的地方隐式使用它。

我用 if-else 结构解决了这个问题:

def data_process(shape_A, shape_B = None):
  # ... some code ...
  res1 = process.shape(shape_A)    # shape A is always used
  if shape_B is not None:
      res2 = process.shape(shape_B)
  else: 
      res2 = process.shape(shape_A)
  return res1, res2

data_process(my_shape_A)  # call 1
data_process(my_shape_A, shape_B=my_shape_B)  # call 2

但是我认为更优雅的方法是在函数定义中使用 shape_B = shape_A 引用 shape_A 作为默认值:

def data_process(shape_A, shape_B = shape_A):
  # ... some code ...
  res1 = process.shape(shape_A)    # shape_A is always used
  res2 = process.shape(shape_B)    # if shape_B not provided, shape_B = shape_A
  return res1, res2

因为简单地这样做给了我引用未知变量的错误,我想知道:有没有办法为其他函数参数引用或重用 Python 函数参数(相同函数)?

这只是一个简单的用例,但我认为基于其他函数参数的默认函数参数对于节省几行代码非常有用。

【问题讨论】:

  • shape_A 在你的函数头中只不过是一个位置参数的名称。您对if-elseNone 的使用是正确的。

标签: python function parameter-passing


【解决方案1】:

不,没有。但是有什么问题

def data_process(shape_A, shape_B = None):
    if shape_B is None:
        shape_B = shape_A
    # rest of function not worrying about whether shape_B was passed or not

?

【讨论】:

  • 谢谢,“不,没有”回答了我的问题,所以我会接受这个。就像你和其他人指出的那样,我想这些版本没有什么问题 - 我只是希望 所有“默认值”逻辑都在一个地方 - 而不是:def fn(一些默认值): '''...一个很长的 fn 文档...''' 一些更多默认值和可能有很多初始化代码rest of the function。我很惊讶,即使显然没有人欣赏我心中的美丽;]
  • 原因是因为python的工作方式。 def f(x=a): pass 在函数被定义 时计算a,而不是在它被调用 时计算。所以a = 3; def f(x = a): passdef f(x = 3) 相同,这很有用。您的建议会使a = 3; def f(a, b=a): pass 模棱两可。
【解决方案2】:

从逻辑或效率的角度来看,我认为您当前的代码没有任何问题。您可以考虑一些替代方案仅出于审美原因

假设一个形状(如果提供)是一个元组。

def data_process2(shape_A, shape_B=None):
    res1 = process.shape(shape_A)
    res2 = process.shape(shape_B if shape_B else shape_A)
    return res1, res2

def data_process3(shape_A, shape_B=None):
    if shape_B:
        shape_B = shape_A
    res1 = process.shape(shape_A)
    res2 = process.shape(shape_B)
    return res1, res2

【讨论】:

  • 这是个坏建议。传递shape_B = 0 与传递shape_B = None 不同,但两者都会导致此代码中的shape_B == shape_A。而是使用shape_B if shape_B is not None else shape_A
  • @FHTMitchell,我不同意。一个形状,如果提供的话,应该是一个元组,例如,(0, 0, 0) 被认为是True。如果用户想让他的代码完全防呆,他应该应用类型检查或try / except(确保没有整数,甚至没有字符串!)。为了说明,请尝试x = np.empty((0)); bool(x.shape)
  • x = np.arange(5); x.shape = 5; print(x) 是有效的 numpy。更重要的是y = np.array([]); y.shape = 0; print(y) 也有效。您对x = np.empty((0)) 的演示是另一个很好的例子,因为(0) != (0,)
  • 你的例子证明了我的观点!当您将形状设置为整数时,它会存储为元组。x = np.arange(5); x.shape = 5; isinstance(x.shape, tuple)。即使对于您的空数组案例..
  • 对,所以将整数形状传递给 numpy 是有效的 python。谁在乎它们是如何存储的?关键是上面的函数 (process.shape) 很可能正在做我正在做的事情,限制它的意义何在?
猜你喜欢
  • 2011-06-02
  • 2013-05-18
  • 2020-12-15
  • 1970-01-01
  • 2018-05-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-10-02
相关资源
最近更新 更多