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

     2023-02-25     61

关键词:

【中文标题】是否有 Python 方法可以访问类的所有非私有和非内置属性?【英文标题】:Is there a Python method to access all non-private and non-builtin attributes of a class? 【发布时间】:2013-06-09 03:07:50 【问题描述】:

我想调用一个方法来给我一个包含所有“非私有”(我在这里使用术语“私有”的术语,因为它在 Python 中并不真正存在)和非内置属性(即那些不以单下划线或双下划线开头的)。类似 vars(MyClass) 的东西只会返回该类的“公共”属性。

我知道

from M import * 

不导入名称以下划线开头的对象。 (http://www.python.org/dev/peps/pep-0008/#id25) import 是如何实现的?通过内置函数还是仅通过检查下划线?这样做的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'

如果我这样做了

vars(MyClass).keys()

我明白了

['_MyClass__gets_name_mangled', '__module__', '_private', '__doc__', '__dict__', '__weakref__', 'public', '__init__']

我怎样才能只得到

['public']

还是我只需要自己检查下划线?似乎有一种pythonic方式可以做到这一点。

有关下划线和双下划线的更多信息,请参阅: What is the meaning of a single- and a double-underscore before an object name?

【问题讨论】:

vars(MyClass).keys()dir(MyClass) 我不知道有什么功能可以做到这一点。总有:[f for f in dir(MyClass) if not f.startswith('_')] @Elazar 如果我的理解是正确的, dir(MyClass) 将返回 MyClass 子类化的类的属性(如果 MyClass 碰巧发生子类化)除了在 MyClass 中定义的那些属性,而 vars(MyClass ) 只返回在 MyClass 中定义的那些属性。细微的差别。但原始问题仍然存在。 其实Pythonic的方式是定义一个函数:def public_vars(klass): return [f for f in vars(MyClass) if f[0] != '_'] 双下划线不代表私有。它的意思是“使用名称修饰”,这只是该类保留与任何子类中的相同属性不同的属性的一种机制 【参考方案1】:

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

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

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


* "在 import * 期间来自某个模块'"

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

模块A 定义了a1a2

模块B 定义了b1b2

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

from A import a1, a2
from B import *

假设我们在模块B 中添加函数a1。现在突然模块C 坏了,虽然我们还没有碰过它。

【讨论】:

出于好奇:import * 是否只是像@Blender 建议的那样检查前导下划线? @andy - 导入 * 被认为是不好的做法,因为您永远无法确定您究竟导入了什么,这反过来又会造成名称冲突和可能意外使用使用 * 导入的方法。最好单独显式导入每个方法,或者简单地从公共命名空间中引用它们。 我认为这是在不使用 exec 的情况下添加隐式绑定的唯一方法。 我明白了。你是说 调用 import * 是不好的做法(这是有道理的)。我以为您是在说import *实现(忽略带有前导下划线的属性)是不好的做法(因为它遵循公共/私有范式)。感谢您的澄清。 @andy 知道了。编辑答案以消除歧义。【参考方案2】:

我正在使用这个功能:

def print_all_public_fields(obj):
    print(obj)
    for a in dir(obj):
        if not a.startswith('_') and not a.isupper():
            print('\t%s = %s' % (a, getattr(obj, a)))

我知道这不是你想要的,但也许它会给你一些想法。

【讨论】:

【参考方案3】:

使用过滤 vars() 的 dict 理解

 k:v for k,v in vars(myObject).items() if not k.startswith('_') 

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

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

【讨论】:

'public'(所需的输出)不是可调用的吗?为什么这是一个过滤条件? 请注意,vars 过滤“魔术”(又名 d'under)方法,这与 dir 不同。对于“private”/s'under,需要此处显示的过滤器。

python中的私有属性和私有方法

Python对于类的成员没有严格的访问控制限制,这与其他面相对对象语言有区别。关于私有属性和私有方法,有如下要点:1、通常我们约定,两个下划线开头的属性是私有的(private)。其他为公共的(public);2、类内部可以访问... 查看详情

《面向对象程序设计》高手进~~~~~~~~~~~~!!

...有成员和保护成员在派生类中认为公有成员和保护成员,可以通过派生类的成员函数访问基类中所有非私有成员。还可通过派生类的对象直接访问基类中的公有成员。protected:基类中的所有公有成员和保护成员都成了保护成员,... 查看详情

从抽象类继承(代码片段)

...actcar中具有私有访问权限”我以为:字段总是私有的子类是否继承了超类的所有字段和方法?我现在该怎么办?答案实例方法和字段由super类的派生类继承,但并不意味着它们也可以访问。在private类中标记为super并由sub类继承的... 查看详情

面向对象(代码片段)

...一种将抽象性函式接口的实现细节部份包装、隐藏起来的方法封装的优点良好的封装能够减少耦合类内部的结构可以自由修改可以对成员变量进行更精确的控制隐藏信息,实现细节实现方式:属性私有+setter()/getter()继承子类继承... 查看详情

访问超类的私有成员

...么?嵌套类可以访问其封闭的所有私有成员类——字段和方法。因此,公共或受保护的嵌套子类继承的类可以间接访问所有超类的私有成员。引用http://docs.oracle.com/javase/tutorial/java/IandI/subc 查看详情

通过反射访问父类的私有成员

...中,子类是不能访问父类的私有成员的,包括成员变量和方法,但可以通过Java的反射机制去访问。  其实在一个子类被创建的时候,首先会在内存中创建一个父类对象,然后在父类对象外部放上子类独有的属性,两者合... 查看详情

从子类访问父类的私有实例变量?

...另一个类,baz,它是extendsfoo。如果foo中没有定义访问器方法,baz中的非静态方法可以访问foo的变量bar吗?顺便说一句,我正在使用Jav 查看详情

有限继承(代码片段)

思考:类中有三大类成员:属性,方法和类常量,还有访问修饰限定符限制,那么继承是子类可以使用父类所有成员吗? 引入:从理论上讲,继承后子类是可以访问父类的所有成员的,但实际上父类有一些成员并不希望被子... 查看详情

python私有变量与私有方法

python的私有化是为了规划私有属性,避免非相关的访问【假如!我有老婆,你不能直接知道我老婆是谁,你只有问我才会知道,即我的私有属性只有我知道】在python中定义私有变量和私有方法只需要在变量名或函数名前加上"__"... 查看详情

java中外部类可以访问非静态内部类的私有属性???

...ass(32).m; 1、创建一个Bean1类,并建好两个私有变量和构造方法。2、创建一个Bean2类,引入对应包,创建好main方法。3、创建 Class<?>clazz=Class.forName("test.Bean1")。4、创建Bean1bean=(Bean1)clazz.newInstance();Field[]fs=clazz.getDeclare... 查看详情

私有属性/方法的问题

...过调用 使用了私有属性的方法达到访问私有属性,但python中并没有真正意义的私有,可以通过 _类名__属性/方法来访问。 例:有一个Woman类,内有私有属性__age和 私有方法 __secret(self)  # 实例化一个小明... 查看详情

this与base关键字

...类的私有成员以外的所有成员。this关键字只能用在实例方法中。作用:  查看详情

java学习--oop

...,继承,多态封装  封装是使用访问限制对类,属性和方法进行访问范围的限定。如果不使用封装则会出现如下情况:将属性私有化则只能通过一种方式进行该变类中的变量,原因是不能访问被私有化的属性和方法。 继承... 查看详情

92.私有属性和私有方法(代码片段)

...对象三大特性:封装、继承、多态封装的意义:将属性和方法放到一起做为一个整体,然后通过实例化对象来处理;隐藏内部实现细节,只需要和对象及其属性和方法交互就可以了;对类的属性和方法增加访问权限控制。私有权... 查看详情

是否可以在私有方法中定义公共变量?

】是否可以在私有方法中定义公共变量?【英文标题】:Isitpossibletodefineapublicvariableinaprivatemethod?【发布时间】:2016-08-2916:57:38【问题描述】:我有一个有2个私有方法的类。在方法A中,我定义了一个变量,比如varA计数。在方法B... 查看详情

python入门-6面向对象编程:06私有属性和私有方法(实现封装)-@property装饰器-get和set方法-总结(代码片段)

一:私有属性和私有方法(实现封装)  Python对于类的成员没有严格的访问控制限制,这与其他面向对象语言有区别。关于私有属性和私有方法,有如下要点:    1.通常我们约定,两个下划线开头的属性是私有的(private)。... 查看详情

python之私有属性(代码片段)

概要在基类的定义中,如果有些属性或者方法,我们希望隐藏它,从而不被子类继承,或者使其不被实例直接访问到,这时候可以用到私有属性的命名方法。尽管类的所有属性和方法在某种意义上说都是“暴露的”,但是私有属... 查看详情

14.11类的成员修饰符(代码片段)

成员修饰符类的所有成员分为:字段,方法  公有成员,在任何地方都能访问  私有成员,只有在类的内部才能访问私有成员和公有成员的定义不同:私有成员命名时,前两个字符是下划线。(特殊成员除外,例如:init、ca... 查看详情