python - 如何从被叫方的同一线路中识别多个调用者?

标签 python

我正在尝试识别同一线路的来电者。下面是一个例子:

def get_file():
    caller_id = get_caller_id()
    return open(caller_id, 'a+')

def write_content():
    with get_file() as f1, get_file() as f2: # line with multiple callers
        f1.write('123')
        f2.write('456')

def fun():
    write_content()
    write_content()
    write_content()
    write_content()
    write_content()

get_caller_id() 函数就是我想要的。它将为函数 id 中的第一次和第二次 get_file() 调用生成两个不同的 write_content() s,但是对于函数 write_content() 中的所有 5 次 fun() 调用,两次 get_file() 调用中的每一次都将在这 5 次 write_content() 调用中返回一个相同的文件对象。

调用 fun() 后,只会生成两个文件,一个内容为'123123123123123',另一个内容为'456456456456456'。返回的caller_id只能对当前运行的session保持一致,python内核重启后caller_id不一致也没关系。

我试过 inspect 模块:

def get_caller_id():
    cur_frame = inspect.currentframe()
    caller_frame = inspect.getouterframes(cur_frame)[2]
    frame_obj = caller_frame[0]
    line_no = caller_frame[2]
    return '{}_{}'.format(id(frame_obj), line_no)

当一行中只有一个get_file()调用时,这个get_caller_id()效果很好。但是对于来自同一线路的多个调用者,它会生成相同的 ID,这不是我想要的。

我搜索了如何在一行中获取调用者的列位置,但一无所获。这种定位可能吗?

谢谢。

编辑:

下面是我实际做的:

class AutoSharedParams(object):
    def __init__(self, dict_key='root', params_dict=None, init_value=None):
        if params_dict is None:
            params_dict = {}
        self._params_dict = params_dict
        self._dict_key = dict_key
        if self._dict_key not in self._params_dict and init_value is not None:
            self.x = init_value

    def __call__(self, init_value=None, func=None):
        caller_frame = inspect.getouterframes(inspect.currentframe())[1]
        caller_id = id(caller_frame[0])
        caller_ln = caller_frame[2]
        key = '{}_c{}_l{}'.format(self._dict_key, caller_id, caller_ln)

        if key not in self._params_dict:
            if func:
                init_value = func()
        else:
            init_value = None

        return AutoSharedParams(dict_key=key, params_dict=self._params_dict, init_value=init_value)

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        return False

    @property
    def x(self):
        if self._dict_key in self._params_dict:
            return self._params_dict[self._dict_key]
        else:
            return None

    @x.setter
    def x(self, value):
        self._params_dict[self._dict_key] = value

我使用 lasagne 创建 CNN(aspAutoSharedParams 的一个实例):

with asp(func=lambda: lasagne.init.HeNormal(gain='relu')) as w:
    l = Conv2DLayer(l, num_filters=16, filter_size=(3, 3), W=w.x)
    w.x = l.W

with asp(init_value=0) as w, asp(init_value=0) as b: # there are two calls in one line
    l = Conv2DLayer(l, num_filters=16, filter_size=(3, 3), W=w.x, b=b.x)
    w.x = l.W
    b.x = l.b

我有很多与上面类似但不同的代码,当这段代码再次通过时,我想分享那些创建的参数( w.xb.x 和许多其他)。最简单的方法是 list.append(w)w=list.pop(0) ,但是当代码中有不同的路径时它会不兼容。所以我需要一把 key 来标记它们。

最佳答案

我想你需要这样的东西:

>>> import inspect
>>> def f():
    curframe = inspect.currentframe()
    curframe = inspect.getouterframes(curframe, 2)
    caller = curframe[1][3]
    if caller == 'f1':
        print "f() called f1()"
    elif caller == "f2":
        print "f() called f2()"
    else:
        print "f() called by an unknwon!"


>>> def f1():
    f()

>>> def f2():
    f()

>>> def f3():
    f()

工作如下:

>>> f1()
f() called f1()
>>> f2()
f() called f2()
>>> f3()
f() called by an unknwon!
>>> 

修改 f() 以对不同的调用者有不同的行为。

关于python - 如何从被叫方的同一线路中识别多个调用者?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36953002/

相关文章:

python - Django 子查询表达式包含混合类型。您必须设置output_field

python - Python 中 switch 语句的替代品?

Python:类似 Haskell 的 ./$

python - Django 模板 : How best can the output of executing python code in a Django template be suppressed?

python - 使用 Keras 使用 ANN 预测正弦

python - 运行 pypi-server 时出现 ValueError : zero length field name in format

python - pandas 数据框中的多个条形图

python - 添加到 session 和提交 flask 时部分数据丢失

Python:回答终端提示

python - 如何使用 python curl 文件