When I teach decorators, I start with a "logged" decorator example:

https://uwpce-pythoncert.github.io/PythonCertDevel/modules/Decorators.html#an-example

def logged_func(func):
    def logged(*args, **kwargs):
        print("Function {} called".format(func.__name__))
        if args:
            print("\twith args: {}".format(args))
        if kwargs:
            print("\twith kwargs: {}".format(kwargs))
        result = func(*args, **kwargs)
        print("\t Result --> {}".format(result))
        return result
    return logged
Interestingly, I don't actually use such a thing in any kind of production, but it's could be a way to ackomplish what's been proposed here.

As a decorator, we usually would expect to use it with the decoration syntax:

@logged
def a_new_func():
   ...

But it would also be used to re-bind a already defined function for testing. using the original example:


while (func1() + 2 * func2()) < func3():

could become "logged" by adding:

func2 = logged(func2)
while (func1() + 2 * func2()) < func3():


I actually like that better than inserting extra code into the line you want to test.

And I"m pretty clueless about what yu can to with inspect -- but maybe some more magic could be added in the decorator if you wanted that.

-CHB





On Fri, Apr 27, 2018 at 6:27 AM, Eric Fahlgren <ericfahlgren@gmail.com> wrote:
I've had a 'dprint' in sitecustomize for years.  It clones 'print' and adds a couple of keyword parameters, 'show_stack' and 'depth', which give control over traceback output (walks back up sys._getframe for 'depth' entries).  It returns the final argument if there is one, otherwise None.  It can be used anywhere and everywhere that builtin print is used, plus anywhere in any expression just passing a single argument.

I thought about replacing standard print with it, but I like the greppability of 'dprint' when it comes time to clean things.


On Fri, Apr 27, 2018 at 6:05 AM, Steven D'Aprano <steve@pearwood.info> wrote:
Actually, I think I can think of a way to make this work, if we're
willing to resurrect some old syntax.

On Fri, Apr 27, 2018 at 09:27:34PM +1000, Steven D'Aprano wrote:
> I think that this is either a great idea or pointless, depending on what
> the built-in actually does.
>
> If all it does is literally the debug print function you give:
>
> > # "debug print": prints and then returns its argument
> > def dp(obj):
> >     print(repr(obj))
> >     return obj
>
> then it is just a trivial helper as you say, and in my opinion too
> trivial to bother making a builtin.

I changed my mind... let's add this as a builtin, under the name
debugprint. It is a completely normal, non-magical function, which takes
four (not one) arguments:


def debugprint(obj, lineno=None, module=None, source=None):
    out = []
    if module is not None:
        if lineno is None:
            lineno = "?"
        out.append(f"Line {lineno} of {module}")
    if source is not None:
        out.append(ascii(source))
    out.append(f"result {repr(obj)}")
    print(', '.join(out))
    return obj


Now let's put all the magic into some syntax. I'm going to suggest
resurrecting the `` backtick syntax from Python 2. If that's not
visually distinct enough, we could double them: ``expression``.

When the compiler sees an expression inside backticks, it grabs the name
of the module, the line number, and the expression source, and compiles
a call to:

    debugprint(expression, lineno, module, source)

in its place. That's the only magic needed, and since it is entirely at
compile-time, all that information should be easily available. (I hope.)
If not, then simply replace the missing values with None.

If the caller shadows debugprint, it is their responsibility to either
give it the correct signature, or not to use the backticks. Since it's
just a normal function call, the worst that happens is that a mismatch
in arguments gives you a TypeError.

Shadowing debugprint would be an easy way to disable backticks on a
per-module basis, at runtime. Simply define:

def debugprint(obj, *args):
    return obj

and Bob's yer uncle.



--
Steve
_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/


_______________________________________________
Python-ideas mailing list
Python-ideas@python.org
https://mail.python.org/mailman/listinfo/python-ideas
Code of Conduct: http://python.org/psf/codeofconduct/




--

Christopher Barker, Ph.D.
Oceanographer

Emergency Response Division
NOAA/NOS/OR&R            (206) 526-6959   voice
7600 Sand Point Way NE   (206) 526-6329   fax
Seattle, WA  98115       (206) 526-6317   main reception

Chris.Barker@noaa.gov