[Tutor] Regarding Python api script

Avi Gross avigross at verizon.net
Fri Dec 7 12:30:18 EST 2018


[[ Real SUBJECT: emulating decorators ]]

Steven,

I am not suggesting that a particular way of reusing a name is a good idea.
I am asking if some ways are encouraged and others are discouraged in the
python community. 

Just to clarify one point you asked about:

#  > I have often seen something like this done with methods, such as to
emulate
#  > decorator functionality where a method is created in an object with a
name
#  > and the very next method created has the same name with the same
function
#  > name as an argument to replace it.
#  
# I don't understand this. Can you show an example? Even if made up?

The answer is that I saw that mentioned in a Lutz book that I no longer
have. What I wrote above should be clear if I give an example:

Say you have a method in a class definition called do_this() that does
whatever this is.

You may also have other methods in the same or different classes with names
like do_that() and your programs run fine.

At a later point you decide you want to see how long it takes the method to
run. So you make or borrow a function called timing_is_everything() that
looks like this in pseudocode:

def timing_is_everything(fun, args):
    save the current time
    call fun with args
    save the return value of calling fun
    get the current time
    calculate time elapsed and do whatever with it.
    Return saved return value from fun.

The argument "fun" above can be replaced by any function such as "do_this"
or "do_that" and produce the same side-effect while also running the
function unharmed.

Then you decide you want a function that logs when another function is
called and with what arguments:

Again, in PSEUDOCODE, it looks like:

def logistics(fun, args):
    with open(logfile):
         write info about the current date/time, name of the function and
arguments
    return result of calling the function with those args

Now to the point. You could write each and every module you want
independently. At the top of the body you could insert any similar code to
begin timing it or to log it. Then you place the code needed for that
function followed by anything you want done after such an action and finally
return a value, if needed.

But if you already have written and tested something like the two modules
above, you can do something like this:

class classy(object):
    ...
    # Original function first of this name
    def recreational_fun(args):
        ...

    # New function, second of this name
    recreational _fun = timing_is_everything(recreational _fun, args)

    # New function, third of this name
    recreational _fun = logistics(recreational _fun, args)

AGAIN, the above is for illustration only and I am well aware of the proper
ways to do the pseudocode such as using notations like *args, **kwargs and
so on. We are talking about an IDEA that perhaps predated the introduction
of decorators way back when. The point is that you could have used three
names here for the various functions but realistically, only the last was
needed so why carry around extra methods.

With "decorators" as a python feature allowing you to wrap multiple
functions around the one being defined, assuming you built the above helper
functions properly so they can be used as decorators, the above might look
like this:

class classified(object):
    ...
    # Original function first and only of this name 
    # and highly decorated bottom to top

    @ logistics
    @ timing_is_everything
    def recreational_fun(args):
        ...

Both ways of doing this, again if PROPERLY done, should have the same
result, albeit there may be subtle changes such as hidden within the dunder
properties. There will be a single function name visible to any user. When
called, it will log an entry, note what time it is, do whatever the
re-created method is supposed to do, then calculate how much time it took
and return some result.

And, yes, I know there is overhead added as you end up with layered function
calls and so on.

This was an answer to a request. I hope I answered it. I do not wish to now
continue on this topic. The topic was not decorators. But the decorator
functionality used above likely does not confuse anybody as to what the name
of the method is. That variable name is only seen once as compared to my
first example when it refers to three completely different functions and
keeps giving up a connection to what effectively becomes an anonymous
function that can only be remembered and called within the enclosing
function.

I tend to agree with the other points Steve made.




More information about the Tutor mailing list