是否有Python方法可以访问类的所有非私有和非内置属性?

and*_*ndy 8 python private public built-in

我想调用一种方法给我一个所有"非私有"的词典(我在这里使用"私有"一词,因为它在Python中并不存在)和非内置属性(即那些在类上不要以单个或双下划线开头.像vars(MyClass)这样的东西只能返回该类的"公共"属性.

我知道

from M import * 
Run Code Online (Sandbox Code Playgroud)

不会导入名称以下划线开头的对象.(http://www.python.org/dev/peps/pep-0008/#id25)导入如何实现?通过内置函数或仅通过检查下划线?什么是pythonic方法呢?

例:

class MyClass(object):
    def __init__(self):
        do_stuff()
    def _private(self):
        print 'private'
    def __gets_name_mangled(self:
        print 'becomes _MyClass__gets_name_mangled()'
    def public(self):
        print 'public'
Run Code Online (Sandbox Code Playgroud)

如果我做

vars(MyClass).keys()
Run Code Online (Sandbox Code Playgroud)

我明白了

['_MyClass__gets_name_mangled', '__module__', '_private', '__doc__', '__dict__', '__weakref__', 'public', '__init__']
Run Code Online (Sandbox Code Playgroud)

我怎么才能得到

['public']
Run Code Online (Sandbox Code Playgroud)

或者我只是需要自己检查下划线?看起来似乎会有一种pythonic方式来做到这一点.

有关下划线和双下划线的更多信息,请参阅:对象名称之前的单下划线和双下划线 的含义是什么?

ker*_*ert 6

使用dict理解过滤vars()

{ k:v for k,v in vars(myObject).items() if not k.startswith('_') }
Run Code Online (Sandbox Code Playgroud)

移入一个函数,该函数返回非“软件专用”或可调用属性的列表。如果愿意,您可以通过如上所述更改dict理解来返回值

def list_public_attributes(input_var):
    return [k for k, v in vars(input_var).items() if
            not (k.startswith('_') or callable(v))]
Run Code Online (Sandbox Code Playgroud)


Rom*_*huk 4

实际上,这样的函数存在是不符合Python规范的——因为“官方”Python中没有私有或受保护的字段/属性。

虽然在某些 module* 期间丢弃带有前导下划线的模块属性(通常是一些实现细节)是有意义的import *,但它在任何其他对象的上下文中没有用。

因此,如果您需要仅列出对象的“公共”方法/属性,只需迭代结果dir并删除带有前导下划线的名称即可。


*“import *在某个模块期间”

通常这不是最佳实践。考虑下一个例子:

模块Aa1定义a2

模块Bb1定义b2

模块中的这段代码C按预期工作:

from A import a1, a2
from B import *
Run Code Online (Sandbox Code Playgroud)

a1想象一下我们在 module 中添加功能B。现在模块突然C坏了,尽管我们还没有碰过它。