kragniz / anyprint

Use any* language's print statements in Python
Do What The F*ck You Want To Public License
402 stars 22 forks source link

Add symbols usually associated with print/debug/log statements #16

Open SylvainDe opened 7 years ago

SylvainDe commented 7 years ago

When using C/C++, whenever I use something like printf, I usually use symbols such as __LINE__ or __FUNC__.

It would be nice to define such symbols.

What is nice is that abusing the __str__ and/or __repr__ logic, it can be done easily: (disclaimer : code is not very tested):


import sys

def func_name(_):
    return sys._getframe(1).f_code.co_name

def line_number(_):
    return str(sys._getframe(1).f_lineno)

def file_name(_):
    return sys._getframe(1).f_code.co_filename

class FunctionNameObject():
    __str__ = func_name
    __repr__ = func_name 

class LineNumberObject():
    __str__ = line_number
    __repr__ = line_number

class FilenameObject():
    __str__ = file_name
    __repr__ = file_name 

__FUNC__ = FunctionNameObject()
__LINE__ = LineNumberObject()
__FILE__ = FilenameObject()

class Titi():
    def __init__(self):
        print(__FILE__, __FUNC__, __LINE__)

def toto():
    def tutu():
        print(__FILE__, __FUNC__, __LINE__)
    tutu()
    print(__FILE__, __FUNC__, __LINE__)

toto()
Titi()
print(__FILE__, __FUNC__, __LINE__)
SylvainDe commented 7 years ago

Oops, I went overboard and wrote the following code:

import sys
import datetime

class FunctionsToStr():
    """Object to represent functions to be called when conversion to str is done.

    This is useful to delegate the computing of the string value to a later point."""
    def __init__(self, func):
        self.func = func

    __str__ = __repr__ = lambda self: self.func()

# Value based on https://gcc.gnu.org/onlinedocs/cpp/Standard-Predefined-Macros.html#Standard-Predefined-Macros
# and https://gcc.gnu.org/onlinedocs/gcc/Function-Names.html
__func__ = __FUNC__ = __FUNCTION__ = FunctionsToStr(lambda: sys._getframe(2).f_code.co_name)
# TODO: __PRETTY_FUNCTION__ could use something more beautiful based on Signature inspection
__PRETTY_FUNCTION__ = FunctionsToStr(lambda: sys._getframe(2).f_code.co_name) 
__LINE__ = FunctionsToStr(lambda: str(sys._getframe(2).f_lineno)) 
__FILE__ = FunctionsToStr(lambda: sys._getframe(2).f_code.co_filename)
# These values are computed only once (at "compilation" time and not at runtime) 
__DATE__ = datetime.datetime.now().strftime("%b %d %Y")
__TIME__ = datetime.datetime.now().strftime("%H:%M:%S")

# Others:
# If it wasn't for the $ prefix, we could use http://tldp.org/LDP/abs/html/internalvariables.html .
# http://php.net/manual/en/language.constants.predefined.php
# http://search.cpan.org/~shay/perl-5.24.2/pod/perldata.pod#Special_Literals

class Titi():
    def __init__(self):
        print(__DATE__, __TIME__, __FILE__, __FUNC__, __LINE__)

def toto():
    def tutu():
        print(__DATE__, __TIME__, __FILE__, __FUNC__, __LINE__)
    tutu()
    print(__DATE__, __TIME__, __FILE__, __FUNC__, __LINE__)

toto()
Titi()
print(__DATE__, __TIME__, __FILE__, __FUNC__, __LINE__)

If you like it, you can reuse it or I can open a PR. Otherwise, feel free to ignore.