Reputation: 19724
I understand this is insane and non-pythonic for a number of reasons, but I'm interesting in seeing how it could be done in order to learn more about the language.
I have about a billion parser functions that I have given names like:
def parser1(x):
do_stuff(x)
def parserN(x,y):
do_other_stuff(x,y)
And I call:
>>> result = parser1(x)
This nomenclature means the code base is less than beautiful, but it works. If I write a new parser, I just increment my file, and hope I counted correctly, didn't make any typos to overwrite something existing, etc.
What I would love, however, is some way of calling them, not by a name I have given them, a name that I have to think up with my dumb human brain, but according to some machine-generated name derived from the contents of the function.
Eg, my ideal would be something like:
parser1 = """def func(x):
do_stuff()"""
print(hashlib.md5(parser1.encode('utf-8')).hexdigest())
>>> print(hashlib.md5(parser1.encode('utf-8')).hexdigest())
"2cb3fed66c79bc14eb442afad27651c8"
>>> result = __2cb3fed66c79bc14eb442afad27651c8(x)
These md5funs could be stored in a dictionary mapping to their implementation, for example, then they could be iterated over, or applied according to some logic, perhaps the logic even coming from other md5funs in the mapping.
How would I do this in python?
Bonus points would be for, not just using the md5 of the string representation of the function, but the md5 of the AST of the function so that:
def parser1(x):
a = 1
do_stuff(x) + a
and
def parser2(y):
b = 1
do_stuff(y) + b
would get the same hash, and mean I don't have to human-name the function twice.
Upvotes: 0
Views: 74
Reputation: 81664
A very crude and dirty way of doing this would be (well, this whole idea is crude and dirty)
import hashlib
def add_md5_to_globals(f):
# Python names can't start with a number
md5 = '_' + hashlib.md5(f.__code__.co_code).hexdigest()
globals()[md5] = globals().pop(f.__name__)
def f(x):
print(x)
add_md5_to_globals(f)
_123fdffc617d4a2514f219cdd26487a3('but why')
# but why
This approach requires you to:
Still come up with names (def f
) but they don't need to be unique. Once add_md5_to_globals
is called, the name 'f'
has no significance and can be reused.
Know the md5 of the function you want to call (for example, _123fdffc617d4a2514f219cdd26487a3('but why')
).
If you don't mind using globals()
in every call, you can return md5
from add_md5_to_globals
and use that to call each function:
latest_md5 = add_md5_to_globals(f)
globals()[latest_md5]('but why')
# but why
Upvotes: 1