1

関数が呼び出されたときの名前を見つけたい...つまり、関数を呼び出した変数の名前。基本的なレシピ、つまり__name__func_name、または基本的なスタックの検査を使用してもうまくいきません。例えば

def somefunc():
    print "My name is: %s" % inspect.stack()[1][3]

a = somefunc
a()
# would output: out: "My name is: somefunc"
# whereas I want it to output: "My name is: a"

私の腸はこれを行うことができると言いますが、それを理解することはできません. Pythonの達人はいますか?

4

2 に答える 2

1

ここでの問題は間接性です。おそらく、スタックを検査し、関数を呼び出したモジュールのコードを取得し、スタックから行番号を解析して、ローカルコンテキストで関数を呼び出すために使用されるラベルを見つけ、それを使用するなど、複雑なことを行うことができますが、とにかくあなたが望むものを必ずしもあなたに与えるとは限りません。検討:

def func(x):
    print get_label_function_called_with()

def func_wrapper(func_in_func_wrapper):
    return func_in_func_wrapper

func_label = func
func_from_func_wrapper = func_wrapper(func_label)
func_from_func_wrapper()

これfuncは、、、、func_in_func_wrapperまたは? 最初は明白な答えのように思えるかもしれませんが、呼び出しているコード内でどのような種類の間接化が行われているのか本当にわからないことを考えると、確実に知ることはできません.func_labelfunc_from_func_wrapper

于 2012-07-18T18:07:20.770 に答える
1

これを 100% 正しく行うことはおそらく不可能ですが、次のことを試してみてください。

import inspect
import parser

# this flatten function is by mike c fletcher
def flatten(l, ltypes=(list, tuple)):
    ltype = type(l)
    l = list(l)
    i = 0
    while i < len(l):
        while isinstance(l[i], ltypes):
            if not l[i]:
                l.pop(i)
                i -= 1
                break
            else:
                l[i:i + 1] = l[i]
        i += 1
    return ltype(l)

# function we're interested in
def a():
    current_func = eval(inspect.stack()[0][3])
    last_frame = inspect.stack()[1]
    calling_code = last_frame[4][0]
    syntax_tree = parser.expr(calling_code)
    syntax_tree_tuple = parser.st2tuple(syntax_tree)
    flat_syntax_tree_tuple = flatten(syntax_tree_tuple)
    list_of_strings = filter(lambda s: type(s)==str,flat_syntax_tree_tuple)
    list_of_valid_strings = []
    for string in list_of_strings:
        try:
            st = parser.expr(string)
            list_of_valid_strings.append(string)
        except:
            pass
    list_of_candidates = filter(lambda s: eval(s)==current_func, list_of_valid_strings)
    print list_of_candidates

# other function
def c():
    pass

a()
b=a
a(),b(),c()
a(),c()
c(),b()

これは印刷されます:

['a']
['a', 'b']
['a', 'b']
['a']
['b']

それはかなり醜くて複雑ですが、必要なものにはうまくいくかもしれません。この関数を呼び出した行で使用されているすべての変数を見つけて、それらを現在の関数と比較することによって機能します。

于 2012-07-18T18:27:59.517 に答える