获取python函数属性而不运行该函数

Get a python function attribute without running the function

我有一个图形用户界面,允许用户从特定的*.py文件运行任何函数。我希望一些函数以不同的方式运行。为了做到这一点,我尝试将属性附加到函数(简单的事情,比如它需要哪些输入)。但是,我发现获得这些属性的唯一方法是首先运行代码。

在不运行代码的情况下,有没有一种方法可以获得这些属性,或者一般来说,有没有一种更为Python式的方法来处理这个任务?

我的代码的基本示例:

菲利普

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
def Beta(x):    
    Beta.input_stype ="Float"
    y = x + 0.5

    return y

def Gamma(x):  
    Gamma.input_stype ="String"
    y = x +"_blah_blah_blah"

    return y

def Delta(x):
    Delta.input_stype ="String"
    y = x.index('WhereIsIt')

    return y

菲利普

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
import FileA
import inspect

z = inspect.getmembers(Fiddle2, inspect.isfunction)

#### User selects the code value here ####

x = user_selection

executable = z[x][1] # Pulls the executable code

if executable.input_stype =="Float" :
    y = executable(45)
elif executable.input_stype =="String" :
    y = executable('Testing_the_WhereIsIt_stuff')


不要在函数体中指定属性:

1
2
3
4
def Beta(x):
    y = x + 0.5
    return y
Beta.input_stype ="Float"

当您使用时,您可能希望使用实际的floatstr类型,而不是字符串"Float""String"。如果您使用的是Python3,那么您可能还需要使用函数注释:

1
2
3
def Beta(x: float):
    y = x + 0.5
    return y


您还可以使用一个修饰器使代码看起来更干净一些,并使信息更接近函数定义,人们在阅读代码时更容易看到这些定义。

1
2
3
4
5
6
7
8
9
10
11
12
13
def input_stype(typ):
    def deco(f):
        f.input_stype = typ
        return f
    return deco

@input_stype('Float')
def Beta(x):
    ...

@input_stype('String')
def Gamma(x):
    ...


您可以在函数定义之后设置属性:

1
2
3
4
5
def Beta(x):    
    y = x + 0.5
    return y

Beta.input_stype ="Float"


我想提出的另一个想法是:

1
2
3
4
5
6
7
8
9
10
11
12
13
def validate_input_type(typ):
    from functools import wraps
    def decorator(f):
        f.input_type = typ
        @wraps(f)
        def wrapper(arg):
            try:
                assert isinstance(arg, typ)
            except AssertionError:
                raise TypeError('{} is not of type {}'.format(arg, typ))
            return f(arg)
        return wrapper  
    return decorator

使用方法如下:

1
2
3
4
5
6
7
@validate_input_type(float)
def foo(x):
    pass

@validate_input_type(str)
def bar(x):
    pass

这将在运行时创建对arg类型的验证,并设置函数的输入类型进行自省。

测验:

1
2
3
4
5
6
7
foo(1) -> TypeError
bar(1) -> TypeError
foo(1.0) -> Ok
bar('aaa') -> Ok

foo.input_type -> float
bar.input_type -> str