Вызывайте функцию с помощью хэша определения, а не тупого заданного человеком имени в Python - PullRequest
0 голосов
/ 27 декабря 2018

Я понимаю, что это безумно и непитонно по ряду причин, но мне интересно посмотреть, как это можно сделать , чтобы узнать больше о языке.

У меня есть около миллиарда функций синтаксического анализатора, которым я дал имена, такие как:

def parser1(x):
  do_stuff(x)

def parserN(x,y):
  do_other_stuff(x,y)

И я вызываю:

>>> result = parser1(x)

Эта номенклатура означает, что кодовая база менее красива, но онаработает.Если я пишу новый синтаксический анализатор, я просто увеличиваю свой файл и надеюсь, что я правильно посчитал, не сделал никаких опечаток, чтобы перезаписать что-то существующее и т. Д.

Однако я хотел бы назвать способ вызоваони не по имени, которое я им дал, имя, которое я должен придумать своим тупым человеческим мозгом, но согласно некоему сгенерированному машиной имени, полученному из содержания функции.

Например, мой идеал будет выглядеть примерно так:

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)

Эти md5funs могут быть сохранены в словаре, отображающем, например, их реализацию, затем они могут быть перебраны или применены согласно некоторой логикевозможно, логика, даже исходящая от других md5funs в отображении.

Как бы я это сделал в python?

Бонусные баллы были бы за, а не только за использование md5 строкового представленияфункция, но md5 AST функции так, чтобы:

def parser1(x):
  a = 1
  do_stuff(x) + a

и

def parser2(y):
  b = 1
  do_stuff(y) + b

получили бы тот же хеш, а значит, мне не нужно человеческое имягоФункция e дважды.

1 Ответ

0 голосов
/ 27 декабря 2018

Очень грубый и грязный способ сделать это (ну, вся эта идея грубая и грязная)

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

Этот подход требует от вас:

  • Все еще придумывают имена (def f), но они не должны быть уникальными.После вызова add_md5_to_globals имя 'f' не имеет значения и может быть использовано повторно.

  • Знайте md5 функции, которую вы хотите вызвать (например, _123fdffc617d4a2514f219cdd26487a3('but why')).

Если вы не возражаете против использования globals() при каждом вызове, вы можете вернуть md5 из add_md5_to_globals и использовать его для вызова каждой функции:

latest_md5 = add_md5_to_globals(f)
globals()[latest_md5]('but why')
# but why
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...