在python中确定方法调用的范围/上下文

时间:2014-02-06 05:25:57

标签: python python-2.7 metaprogramming decorator metaclass

我想为python类方法编写一个装饰器,它可以确定是从公共上下文还是私有上下文调用该方法。例如,给出以下代码

def public_check_decorator(f):
    def wrapper(self):
        if self.f is `called publicly`:  # <-- how do I make this line work correctly?
            print 'called publicly'
        else:
            print 'called privately'
        return f(self)
    return wrapper

class C(object):
    @public_check_decorator
    def public_method(self):
        pass

    def calls_public_method(self):
        self.public_method()

运行时执行最好看起来像这样:

>>> c = C()
>>> c.public_method()
called publicly

>>> c.calls_public_method()
called privately

有没有办法在python中这样做?也就是说,改变行

if self.f is `called publicly`:  # <-- how do I make this line work correctly?

给出所需的输出?

2 个答案:

答案 0 :(得分:0)

其中一些似乎试图对抗“蟒蛇”的潮流。这是合适的吗?

你知道双重非核心标准吗?它使方法“更私密”:

>>> class C(object):
...    def __hide_me(self):
...        return 11
...    def public(self):
...        return self.__hide_me()
...
>>> c = C()
>>> c.__hide_me()
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'C' object has no attribute '__hide_me'
>>> c.public()
11
>>> c._C__hide_me()
11
>>>

那个私密吗?使用这种技术是pythonic。

答案 1 :(得分:0)

鉴于包的名称决定是从私有上下文还是从公共上下文调用函数:

import inspect
import re


def run():
    package_name = '/my_package/'
    p = re.match(r'^.*' + package_name, inspect.stack()[0].filename).group()
    is_private_call = any(re.match(p, frame.filename) is not None for frame in inspect.stack()[1:])
    print(is_private_call)

尝试从包内运行,然后从包外面运行!!! 见inspect.stack()