2

I have a GUI which allows the user to run any function from a specific *.py file. I'd like some of the functions to run in a different manner than each other. In order to do that, I was trying to attach attributes to the function (Simple things like which inputs it needs). However, I found the only way to get those attributes was to run the code first.

Is there a way to get these attributes without running the code, or perhaps a more pythonic way to approach this task in general?

Very rudimentary example of my code:

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')
Mike Müller
86.1k21 gold badges174 silver badges165 bronze badges
asked May 16, 2016 at 20:06
1

4 Answers 4

5

Don't assign the attributes inside the function body:

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

While you're at it, you may want to use the actual float or str types instead of the strings "Float" and "String". If you're on Python 3, you may also want to use function annotations:

def Beta(x: float):
 y = x + 0.5
 return y
answered May 16, 2016 at 20:11
Sign up to request clarification or add additional context in comments.

1 Comment

Yup, that did it. Thanks!
4

You may also be able to make the code look a little cleaner, and keep the information closer to the function definition where people are more likely to look when reading your code, by using a decorator.

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):
 ...
answered May 16, 2016 at 20:24

2 Comments

oh, I just noticed your answer.... I was working on my code and hadn't refreshed the screen
This works well, as long as I move the def input_stype(type) function to another py file. I'm pulling all functions in the given file, and this adds another function to it. Thanks for answer
3

You can set the attribute right after the function definition:

def Beta(x): 
 y = x + 0.5
 return y
Beta.input_stype = "Float"
answered May 16, 2016 at 20:10

Comments

1

Another idea I wanted to suggest:

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

To be used like this:

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

This creates validation of the type of the arg at runtime AND sets input_type on the function for introspection.

Tests:

foo(1) -> TypeError
bar(1) -> TypeError
foo(1.0) -> Ok
bar('aaa') -> Ok
foo.input_type -> float
bar.input_type -> str
answered May 16, 2016 at 20:55

1 Comment

Newer versions of python (>=3.4) have a similar feature built-in using functools.singledispatch. You would still need to have a wrapper like yours to do everything within a single decorator though. And it comes with the additional limitation that you can only have a single argument, which seems like a weird limitation. Frankly, I'm kind of surprised the feature made it into python at all.

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.