2016-05-16 20 views
2

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

有没有办法在不运行代码的情况下获得这些属性,或者可能是一种通常更接近这个任务的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') 
+0

的[Python中的参数类型检查(http://stackoverflow.com/questions/734368/type-checking-of-arguments-python) – Natecat

回答

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 
+0

是的,它做到了。谢谢! – Helos35

3

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

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

Beta.input_stype = "Float" 
+0

完美的作品可能的复制,谢谢 – Helos35

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

哦,我只是注意到你的答案....我正在处理我的代码,并没有刷新屏幕 –

+0

这很好,只要我将def input_stype(type)函数移动到另一个py文件。我拉给定的文件中的所有功能,这增加了另一个功能。 感谢您的回答 – Helos35

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 
+1

较新版本的python(> = 3.4)使用['functools.singledispatch']内置了类似的功能(https://docs.python.org/3.4/library/functools.html#functools .singledispatch)。尽管如此,你仍然需要像你一样的包装器来完成单个装饰器中的所有事情。它带有额外的限制,你只能有一个参数,这似乎是一个奇怪的限制。坦率地说,我很惊讶这个功能让它变成了python。 –