Showing posts with label Python2. Show all posts
Showing posts with label Python2. Show all posts

Monday, January 30, 2017

Finding the arity of a Python function

By Vasudev Ram

While browsing through some Python code, I had the idea of trying to find the arity of a Python function. The arity of a function is the number of arguments it takes.

Digression: I had first come across the concept of arity when reading some books on functional or logic programming, years ago. E.g. Prolog has the concept of arity, IIRC. Just did a quick search for the phrase prolog arity and found a few results confirming this. Here is one, from cse.unsw.edu.au:

arity (link 1)

But in Prolog, the word arity is related to a functor (link 2), not a function, according to the page at link 2.

Excerpt from link 1:

[ The arity of a functor is the number of arguments it takes. For example, the arity of likes/2, as in likes(jane, pizza), is 2, as it takes two arguments, jane and pizza. ]

In fact the use of likes/2 gives a clue to the fact that the Erlang language was influenced by Prolog (and I've read that the first version of Erlang was written in Prolog), because a function foo with arity 2 in Erlang is written as foo/2, as for the Prolog functor above.

[ Note: I'm not an expert in either Prolog or Erlang; these are just casual observations. Anyone who knows better, feel free to comment / correct. ]

Anyway, end of digression.

Here is the code I came up with to find the arity of a Python function. I've used the isfunction and getargspec functions of the inspect module.
'''
function_arity.py
Purpose: To find the arity of a Python function.
Author: Vasudev Ram
Copyright 2017 Vasudev Ram
Web site: https://vasudevram.github.io
Blog: https://jugad2.blogspot.com
Product store: https://gumroad.com/vasudevram
'''

import inspect

# Define a few functions with increasing arity:

def f0():
    pass

def f1(a1):
    pass

def f2(a1, a2):
    pass

def f3(a1, a2, a3):
    pass

def f4(a1, a2, a3, a4):
    pass

def main():

    # Define a few non-function objects:
    int1 = 0
    float1 = 0.0 
    str1 = ''
    tup1 = ()
    lis1 = []

    # Test the function arity-finding code with both the functions 
    # and the non-function objects:
    for o in (f0, f1, f2, f3, f4, int1, float1, str1, tup1, lis1):
        if not inspect.isfunction(o):
            print repr(o), 'is not a function'
            continue
        n_args = len(inspect.getargspec(o)[0])
        if n_args == 0:
            num_suffix = '(no) args'
        elif n_args == 1:
            num_suffix = 'arg'
        else:
            num_suffix = 'args'
        print o.__name__, 'is a function that takes', \
            n_args, num_suffix
    
if __name__ == '__main__':
    main()
And here is the output when I run the program:
$ python function_arity.py
f0 is a function that takes 0 (no) args
f1 is a function that takes 1 arg
f2 is a function that takes 2 args
f3 is a function that takes 3 args
f4 is a function that takes 4 args
0 is not a function
0.0 is not a function
'' is not a function
() is not a function
[] is not a function

I also did a web search:

https://www.google.com/search?q=find+the+arity+of+python+function

in which one hit showed another way of doing it (using gettattr). This StackOverflow question:

How to find out the arity of a method in Python

had some answers; the ones by Python guru Alex Martelli (the martellibot) and Anurag Uniyal were interesting.

Enjoy.

- Vasudev Ram - Online Python training and consulting

Get updates (via Gumroad) on my forthcoming apps and content.

Jump to posts: Python * DLang * xtopdf

Subscribe to my blog by email

My ActiveState Code recipes

Follow me on: LinkedIn * Twitter

Managed WordPress Hosting by FlyWheel



Wednesday, April 10, 2013

Using sys._current_frames() and the Python traceback module for debugging

By Vasudev Ram

Python's sys._current_frames() function/method and the traceback module of Python can be useful for debugging your Python code.

In the example below, I've used py, the Python Launcher for Windows. It comes with Python 3.3. If you're on Python 2, you can download the py launcher for Python 2 here. Use either of the versions (32-bit or 64-bit, as appropriate) called launcher*, not launchwin*, for the commands below.

The example below works on both Python 2 and Python 3.

#--------------------------------------------------------
# test_current_frames.py 

import sys, traceback

def foo():

    for thread, frame in sys._current_frames().items():
        print('Thread 0x%x' % thread)
        traceback.print_stack(frame)

def bar():
    foo()

def baz():
    bar()

baz()
#--------------------------------------------------------

Run the program with any of the following 3 commands:
py test_current_frames.py

or

py -2 test_current_frames.py

or

py -3 test_current_frames.py
You should get output similar to this:
Thread 0x17dc
  File "test_current_frames.py", line 17, in 
    baz()
  File "test_current_frames.py", line 15, in baz
    bar()
  File "test_current_frames.py", line 12, in bar
    foo()
  File "test_current_frames.py", line 9, in foo
    traceback.print_stack(frame)

Also read more about the traceback module on Doug Hellmann's Python Module Of The Week (PyMOTW) site, a.k.a. PyMOTW.

- Vasudev Ram - Dancing Bison Enterprises

Monday, April 8, 2013

py, the Python Launcher for Windows

By Vasudev Ram

py, or py.exe, is the name of a new(ish) Python Launcher for Windows, which was released as part of Python 3.x.

This is the PEP for py.

I tried out Py and it worked okay, for some basic uses.

It lets you launch a specific version of Python, either 2, or 3, or 2.x or 3.x. I tried using it to launch both Python 2.7.3 and Python 3.3.1.

Examples:
C:\> py -V
Python 2.7.3
C:\> py -3 -V
Python 3.3.1
c:\Python33\Tools\Scripts> py -2 which.py py.exe
C:\Windows\py.exe
c:\Python33\Tools\Scripts>py -2 which.py cmd.exe
C:\Windows\system32\cmd.exe

Here is the partial output of running the py --help command:
c:\Python33\Tools\Scripts>py --help
Python Launcher for Windows Version 3.3.1150.1013

usage: py [ launcher-arguments ] script [ script-arguments ]

Launcher arguments:

-2     : Launch the latest Python 2.x version
-3     : Launch the latest Python 3.x version
-X.Y   : Launch the specified Python version
-X.Y-32: Launch the specified 32bit Python version

- Vasudev Ram - Dancing Bison Enterprises

Sunday, November 18, 2012

The Python Data model (for v2 and v3)

3. Data model — Python v2.7.3 documentation

Useful long page about some Python internals.

There is a similar page for Python 3:

http://docs.python.org/3.2/reference/datamodel.html

- Vasudev Ram
www.dancingbison.com

Saturday, April 23, 2011

Six 1.0.0, Python 2 and 3 compatibility library, released

By Vasudev Ram - http://www.dancingbison.com

Six 1.0.0 has been released. Six is a Python 2 and 3 compatibility library. It "provides utility functions for smoothing over the differences between the Python versions with the goal of writing Python code that is compatible on both Python versions."

Six is available here on PyPI (the Python Package Index):

http://pypi.python.org/pypi/six

The creator of six is Benjamin Peterson who is a member of the core Python developers' team.

Posted via email
- Vasudev Ram
Dancing Bison Enterprises