【问题标题】:How to enforce automatic parameter casting in function definitions?如何在函数定义中强制执行自动参数转换?
【发布时间】:2013-03-29 07:30:12
【问题描述】:

考虑这个函数(及其用途)的例子,它接收一个仅作为int 有意义的参数:

def fun(index):
    index = int(index)
    # do something with index

def main():
    print fun(1e6)

我发现我在几个处理整数的函数上不断重复这种模式,因为它确保我确实收到了一些整数(请注意,1e6 是一个浮点实例)。

这有点麻烦,如果忘记它可能会产生问题(有 代码对浮点/整数/字符串/...值的反应不同)。那么这是否可以以某种方式编码在函数签名中?

例如类似于此伪代码的内容:

def fun(int index):
    # do something with index

【问题讨论】:

  • 这有点无法回答(因为我从未真正与他们合作过),但有一些框架作品(我认为是 zope)可以为你做到这一点
  • 类型强制不是 Pythonic。您是否有任何理由避免使用鸭式打字范式?
  • @JoelCornett:与0 相比,舍入误差(源于浮点数的指数符号)会导致问题,并且我有一些循环过冲。 (但我正在学习 Python,来自 C++ 和 Haskell --- 所以我对我无法接受鸭式打字并不感到惊讶。)
  • 如果您打算使用index 进行循环,请将其用作range(index)。如果你给它一个不能表示为整数的对象,那将引发异常。

标签: python types type-conversion


【解决方案1】:

首先,你真的不应该这样做(尽管有些日子我也想这样做……)。 Python 不是静态类型的,因此您不应该真正引入笨拙的静态类型。

Buuut,回答你的问题。 Decorators:

def ensure_int(fn):
    def wrapper(num):
        return fn(int(num))
    return wrapper

def test(num):
    return num + 2

@ensure_int
def test2(num):
    return num + 2

作品如下:

> test("2") 
ERROR!!!

>test2("2")
4

【讨论】:

  • 这会以1e65 为论据表现不佳
  • 感谢您的指出!有一些边缘情况需要处理,但我将把它作为练习留给用户。 (提示,转换为 int 然后 str) ;)
  • 嗯,我必须为每个函数签名实现一个装饰器(你通常有额外的参数,不一定有这个限制),这确实比有用更麻烦。我更多的是考虑接近单个形式参数的规范
  • +1 "Python 不是静态类型的"。如果您不知道要传递给函数的内容,那么返回的内容是否重要?
  • @bitmask 如果您使用的是 Python 3,您可以使用函数注释来做一些事情,如 BrenBarn 所述。真的,你应该以任何一种特别的方式来做这件事(即,除非你正在为 Python 编写一个类型系统,这比实际更学术)。您应该编写整齐组合的函数,而不是到处进行类型转换(非常不符合 Python 风格)。
【解决方案2】:

在 Python 3 中,您可以使用 function annotations,然后编写一个装饰器,将参数转换(或尝试转换)为您指定的类型。

在 Python 2 中,您无法以您想要的方式执行此操作。 Python 2 的语法不支持在函数定义中放入除参数本身之外的任何内容,并且您无法更改 Python 的语法以让您也将类型放入其中。

【讨论】:

猜你喜欢
  • 2020-05-12
  • 2011-10-24
  • 2021-03-30
  • 1970-01-01
  • 1970-01-01
  • 2021-01-26
  • 2016-07-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多