2016-05-16 21 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。 –