Question

I'm trying to implement strong type genetic programming in python.

Is there something like these sample?

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

output: <class 'Integer'>

and

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

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

update:

I'm trying to generate python's expression and avoiding something cannot be evaluated like this:

funcA(20, funcA(True, "text"))
Was it helpful?

Solution 2

Python 3 introduces function annotations. By themselves they don't do anything, but you can write your own enforcement:

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

@strict
def funcA(a: int, b: int) -> int:
    return a + b 

OTHER TIPS

In Python, a dynamically typed language, the type information of a function's parameters is required at runtime. In 3.3 and later, you can get the type of a function as follows:

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'>

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

you can check that with annotations:

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

and the same with parameters:

>>> func.__annotations__["a"]
<class 'str'>

In Python return type is not known until the call is performed and return statement is executed. It even can be different in different situations, so a brief answer is "not possible".

If you need to know the return type for certain function, you still may wrap it into some type checking code that also may expose the return type. However, that would be rather unpythonic:

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: You may do the same to parameter types and check them as well.

the best way is to use docstrings to store such information of the function and

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

In [50]: funcA.__doc__
Out[50]: ' returns an int '

no chance. since python uses duck typing, you could pass parameters of different types, e.g. int and int, str and str, etc. to funcA. there is no chance to tell what return type and parameter type can be without seeing actual parameters

It is impossible to know from just the function as given that it should only be valid for integers. If you call it with integer parameters:

funcA(1, 2)

You get 3, an Integer, but what about this:

funcA("Test", "Test")

You get "TestTest", a string! This technically works, but whether or not it should be used that way is information that just doesn't exist in the code you provide.

In more modern Python, annotations provide the potentially to explicitly state this kind of information, or potentially you could try to infer it from existing usage or from the code of the function, but which of those options (if any) make sense for your use case will depend heavily on the specifics of what you want to do.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top