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

时间:2016-05-16 20:06:38

标签: python

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

有没有办法在不运行代码的情况下获取这些属性,或者通常采用更加pythonic的方式来处理此任务?

我的代码的非常基本的例子:

FileA.py

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

FileB.py

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

4 个答案:

答案 0 :(得分:5)

不要在函数体内分配属性:

def Beta(x):
    y = x + 0.5
    return y
Beta.input_stype = "Float"

虽然您正在使用它,但您可能希望使用实际的floatstr类型而不是字符串"Float""String"。如果您使用的是Python 3,则可能还需要使用函数注释:

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

答案 1 :(得分:4)

您也可以通过使用装饰器使代码看起来更清晰,并使信息更接近人们在阅读代码时更有可能看到的功能定义。

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):
    ...

答案 2 :(得分:3)

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

def Beta(x):     
    y = x + 0.5
    return y

Beta.input_stype = "Float"

答案 3 :(得分:1)

我想提出的另一个想法:

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

要像这样使用:

@validate_input_type(float)
def foo(x):
    pass

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

这会在运行时创建arg类型的验证,并在内省函数上设置input_type。

试验:

foo(1) -> TypeError
bar(1) -> TypeError
foo(1.0) -> Ok
bar('aaa') -> Ok

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