9

我正在尝试在 python 中实现强类型遗传编程。

有类似这些样本的东西吗?

def funcA(a,b):
  return a + b
return_type(funcA)

output: <class 'Integer'>

def funcA(a,b):
  return a + b
parameter_type(funcA)

output: [<class 'Integer'>,<class 'Integer'>]

更新:

我正在尝试生成python的表达式并避免无法像这样评估某些内容:

funcA(20, funcA(True, "text"))
4

7 回答 7

13

在 Python 这种动态类型语言中,函数参数的类型信息是在运行时需要的。在 3.3 及更高版本中,您可以通过以下方式获取函数的类型:

from inspect import signature
def foo(a, *, b:int, **kwargs):
...     pass

sig = signature(foo)

str(sig)
'(a, *, b:int, **kwargs)'

str(sig.parameters['b'])
'b:int'

sig.parameters['b'].annotation
<class 'int'>

https://docs.python.org/3/library/inspect.html#introspecting-callables-with-the-signature-object

于 2018-05-04T18:35:17.567 回答
8

Python 3 引入了函数注解。他们自己什么都不做,但您可以编写自己的强制执行:

def strict(fun):
    # inspect annotations and check types on call

@strict
def funcA(a: int, b: int) -> int:
    return a + b 
于 2013-03-04T11:08:14.103 回答
5

您可以使用注释进行检查:

>>> def func(a: str) -> int:
       # code
>>> func.__annotations__["return"]
<class 'int'>

与参数相同:

>>> func.__annotations__["a"]
<class 'str'>
于 2021-05-03T12:33:50.713 回答
4

return在 Python 中,在执行调用和执行语句之前,返回类型是未知的。在不同的情况下甚至可能会有所不同,因此简短的回答是“不可能”。

如果您需要知道某个函数的返回类型,您仍然可以将其包装到一些类型检查代码中,这些代码也可能会暴露返回类型。但是,那将是相当不合情理的:

def declare_return_type(t):
    def decorator(f):
        def wrapper(*a, **kw):
            res = f(*a, **kw)
            assert isinstance(res, t)
            return res
        wrapper.return_type = t
        return wrapper
    return decorator

@declare_return_type(int)
def f(a, b):
    return a + b

print f.return_type

print f(1, 2) # ok
f('a', 'b') # Assertion error

UPD:您可以对参数类型执行相同的操作并检查它们。

于 2013-03-04T11:14:43.710 回答
2

最好的方法是使用文档字符串来存储函数的这些信息和

In [49]: def funcA(a,b):
   ....:     ''' returns an int '''
   ....:     return int(a+b)
   ....:

In [50]: funcA.__doc__
Out[50]: ' returns an int '
于 2013-03-04T11:06:56.960 回答
0

没有机会。由于python 使用duck 类型,您可以将不同类型的参数,例如int 和int、str 和str 等传递给funcA。没有看到实际参数就没有机会知道返回类型和参数类型是什么

于 2013-03-04T11:06:11.383 回答
0

仅仅从给定的函数中不可能知道它应该只对整数有效。如果您使用整数参数调用它:

funcA(1, 2)

你得到3一个整数,但是这个呢:

funcA("Test", "Test")

你得到"TestTest"一个字符串!这在技术上是可行的,但是否应该以这种方式使用它是您提供的代码中不存在的信息。

在更现代的 Python 中,注释提供了显式声明此类信息的可能性,或者您可能尝试从现有用法或函数代码中推断出它,但这些选项中的哪一个(如果有)对您的使用有意义案例将在很大程度上取决于您想要做什么的细节。

于 2013-03-04T11:08:49.867 回答