访问模块类中的私有模块成员

时间:2014-07-09 08:33:05

标签: python python-2.7

我非常喜欢C ++在课堂上拥有私有,受保护和公共范围的功能。我也喜欢隐藏库用户的实现细节并阻止库API用户无意中搞乱内部细节(例如使用private范围,匿名命名空间)。

我知道在Python中对此的支持是有限的,并且它是争用的来源:一些人认为隐私应该被传达的唯一方式是通过单个下划线_bla,而其他人认为这两者都是应使用单引号和双引号,_bla表示受保护,__bla表示敏感的实现详细信息(例如,请参阅What is the benefit of private name mangling in Python?)。

因此,我想要实现的是在模块中使用一些双下划线私有成员,然后从模块范围中定义的其他函数和类访问这些方法。

从公共模块成员函数访问私有模块成员工作正常,但看起来这不起作用(不依赖于名称去变换或解决方法)来自模块中的类:

#! /usr/bin/env python

def func1():
    print "in func1()"

def _func2():
    print "in _func2()"

def __func3():
    # will be name-mangled due to leading double-underscore
    print "in __func3()"

def publicFunc():
    print "publicFunc() start"
    __func3()
    print "publicFunc() end"

class Foo:
    def __init__(self):
        print "Foo.__init__() start"
        func1()
        _func2()
        __func3()
        # :( Doesn't work, gives
        # NameError: global name '_Foo__func3' is not defined
        print "Foo.__init__() end"

publicFunc()
f = Foo()

运行以上打印:

publicFunc() start
in __func3()
publicFunc() end
Foo.__init__() start
in func1()
in _func2()
<... stack trace>
NameError: global name '_Foo__func3' is not defined

这不是我所期望的 - 我假设函数和类在词法范围和错误方面具有大致相同的行为。我希望它与C ++中的private概念大致相符,我可以从主类中定义的类中访问私有细节,例如。

#include <cstdio>

class A
{
public:
    class B
    {
    public:
        static void fooB() {  A::foo(); }
    };
private:
    static void foo() { printf("in foo\n"); }
};

int main(int argc, char ** argv)
{
    A::B::fooB();
}

打印

in foo

我还希望它可以起到与C ++中匿名命名空间类似的作用,这在编写库的用户不应该(或不必)知道的实现细节时非常有用。 / p>

以下是我尝试过的一些解决方法。他们都没有让我觉得特别优雅:

_funcList = [__func3]
__funcList = [__func3]

class Foo2:
    def __init__(self):
        print "Foo.__init__() start"
        func1()
        _func2()
        # __func3()

        # Work-around 1 - ugly but OK for globals, but not non-locals
        f3 = globals()["__func3"]
        f3()

        # Work-around 2 - misses the point, because now __func3 is
        # readily accessible without needing to mangle method names.
        # With my C++ hat on, this would be roughly equivalent to
        # returning a pointer to a private member function via
        # a protected member function.
        _funcList[0]()

        # Attempt 3 - hoping beyond hope that wrapping the method
        # tag in a private list doesn't work
        global __funcList
        __funcList[0]()
        # results in:
        # NameError: global name '_Foo2__funcList' is not defined
        print "Foo.__init__() end"

模块类的实现细节无法访问模块的私有成员(或者我在某处犯了错误,这似乎很遗憾?)。

以下是我的问题:

  1. 双重下划线是否真的只是为了防止子类分类时出现屏蔽问题?如果是这样,那么我想在我想要隐藏实现细节的所有其他情况下应该使用单个下划线。
  2. 是否有更优雅的隐藏实施细节的方式,他们的目标是同时拥有“受保护”的概念。范围和私人&#39;范围?
  3. 谢谢!

0 个答案:

没有答案