Movatterモバイル変換


[0]ホーム

URL:


Skip to content
DEV Community
Log in Create account

DEV Community

Chris White
Chris White

Posted on

     

Advanced Function Calling in Python

Introduction

Python has a few interesting ways to call functions. This guide will show a few interesting ways to do so that's outside of a standard function call. These techniques can be used for more advanced cases, especially dynamic calling.

Partials

Partials are essentially templates for how a function is called. Take for example a common json dumps I use to give indented JSON output:

fromjsonimportdumpstest_dictionary={'a':'foo','b':'bar'}print(dumps(test_dictionary,indent=2,default=str))
Enter fullscreen modeExit fullscreen mode

Now the thing is I'm always going to be calling it this way. It indents by 2 spaces making it easier to read, anddefault=str defaults to using thestr() construct when it can't parse normally (this happens frequently for some timestamp related values). Calling it this way is a bit verbose, so we can use a partial instead:

fromfunctoolsimportpartialfromjsonimportdumpstest_dictionary={'a':'foo','b':'bar'}indented_json=partial(dumps,indent=2,default=str)print(indented_json(test_dictionary))
Enter fullscreen modeExit fullscreen mode

This is nice because it prevents the need to write function just for the purpose of calling other functions, especially if there's a lot of arguments going with it. Note that any required arguments not present in the partial will need to be filled in during the call.

Dynamic Keyword Args

Python has an interesting mechanism for passing in keyword args as a dictionary of name-> value pairs:

fromjsonimportdumpsvalues={'a':1,'b':2,'c':3}keyword_args={'indent':2,'default':str}print(dumps(values,**keyword_args))
Enter fullscreen modeExit fullscreen mode

The** operator is often referred to as splat, or unpacking as well. This is the equivalent call wise to:

dumps(values,indent=2,default=str)
Enter fullscreen modeExit fullscreen mode

This can be useful in some boto calls where you're building up values to pass on. DynamoDB in particular can utilize this to build up filters and query expressions.

Function Mapping

In cases of calling a function via a string, a mapping using something like a dictionary makes this possible:

defdouble_values(value):returnvalue**2function_mapping={'double':double_values}print(function_mapping['double'](2))
Enter fullscreen modeExit fullscreen mode

I prefer this toeval() usage as it essentially lets me create an approved list of functions to call.

Dynamic Method Calling

Now methods are essentially attributes of a class or class instance. For static methods bound to the class itself (not reliant onself variables),getattr can simply be used with the class and method name:

classTest:@staticmethoddefhello_world():return"Hello, World"hello_method=getattr(Test,'hello_world')print(hello_method())
Enter fullscreen modeExit fullscreen mode

Now if the class name is also dynamic, you need to either access it viaglobals() like so:

classTest:@staticmethoddefhello_world():return"Hello, World"hello_method=getattr(globals()['Test'],'hello_world')print(hello_method())
Enter fullscreen modeExit fullscreen mode

or if it's part of the module thengetattr can be used on the namespace declaration to obtain it:

importcsvwriter_class=getattr(csv,'DictWriter')
Enter fullscreen modeExit fullscreen mode

This could then be passed togetattr again to obtain method inDictWriter. For this to work on class instances (ie. keeping self type values isolated) thengetattr will need to be done on the class instance assignment itself:

classMath:def__init__(self,value=2):self.value=valuedefdouble(self):returnself.value**2math_instance=Math()math_instance2=Math(4)double_method=getattr(math_instance,'double')double_method2=getattr(math_instance2,'double')print(double_method())print(double_method2())
Enter fullscreen modeExit fullscreen mode

Note that if you're using this for something like dynamic plugin calls consider something likeAbstract Base Class to to ensure a consistent method name exists to be executed (run_plugin for example).

Conclusion

That's it for this lesson on advanced ways to do function (and method) calls in Python. If you like what you seeI'm available for hire.

Top comments(0)

Subscribe
pic
Create template

Templates let you quickly answer FAQs or store snippets for re-use.

Dismiss

Are you sure you want to hide this comment? It will become hidden in your post, but will still be visible via the comment'spermalink.

For further actions, you may consider blocking this person and/orreporting abuse

Like what you see? I'm currently open for work opportunities!
  • Location
    Austin, Texas
  • Work
    Open for work
  • Joined

More fromChris White

DEV Community

We're a place where coders share, stay up-to-date and grow their careers.

Log in Create account

[8]ページ先頭

©2009-2025 Movatter.jp