Python 中私有方法和受保护方法的继承

2025-03-13 09:13:00
admin
原创
67
摘要:问题描述:我知道,Python 中没有“真正的”私有/受保护方法。这种方法不是为了隐藏任何东西;我只是想了解 Python 的作用。class Parent(object): def _protected(self): pass def __private(self): ...

问题描述:

我知道,Python 中没有“真正的”私有/受保护方法。这种方法不是为了隐藏任何东西;我只是想了解 Python 的作用。

class Parent(object):
    def _protected(self):
        pass

    def __private(self):
        pass

class Child(Parent):
    def foo(self):
        self._protected()   # This works

    def bar(self):
        self.__private()    # This doesn't work, I get a AttributeError:
                            # 'Child' object has no attribute '_Child__private'

那么,这种行为是否意味着“受保护”的方法将被继承,而“私有”的方法则根本不会继承?

还是我遗漏了什么?


解决方案 1:

Python 没有隐私模型,没有像 C++、C# 或 Java 那样的访问修饰符。没有真正“受保护”或“私有”的属性。

以双下划线开头且不以双下划线结尾的名称会被修饰,以防止在继承时发生冲突。子类可以定义自己的__private()方法,这些方法不会干扰父类中的相同名称。此类名称被视为类私有的;它们仍然可以从类外部访问,但意外冲突的可能性要小得多。

混淆是通过在任何此类名称前面添加一个额外的下划线和类名(无论名称如何使用或是否存在)来完成的,从而有效地为它们提供了一个命名空间。在Parent类中,任何__private标识符(在编译时)都被名称替换_Parent__private,而在Child类中,标识符_Child__private在类定义中的所有位置都被替换为。

以下操作有效:

class Child(Parent):
    def foo(self):
        self._protected()

    def bar(self):
        self._Parent__private()

请参阅词法分析文档中的标识符保留类:

__*

类私有名称。此类名称在类定义上下文中使用时,将被重写为使用混乱形式,以帮助避免基类和派生类的“私有”属性之间发生名称冲突。

以及关于名称的参考文献:

私有名称改编:当类定义中文本出现的标识符以两个或多个下划线字符开头,但不以两个或多个下划线结尾时,它被视为该类的私有名称。私有名称在生成代码之前会转换为更长的形式。转换会将类名插入名称前面,删除前导下划线并插入单个下划线。例如,__spam名为 Ham 的类中出现的标识符将转换为_Ham__spam。此转换与标识符使用的语法上下文无关。

不要使用类私有名称,除非您明确希望避免必须告知想要对您的类进行子类化的开发人员他们不能使用某些名称,否则可能会破坏您的类。除了已发布的框架和库之外,此功能几乎没有用处。

PEP 8 Python 风格指南对私有名称修改有如下说明:

如果您的类打算被子类化,并且您有不想让子类使用的属性,请考虑使用双前下划线命名它们,而不使用尾部下划线。这会调用 Python 的名称改编算法,其中类的名称被改编为属性名称。这有助于避免在子类无意中包含同名属性时发生属性名称冲突。

注 1:请注意,在混乱的名称中仅使用简单类名,因此如果子类选择相同的类名和属性名,仍然会发生名称冲突。

注 2:名称修改可能会使某些用途(例如调试和
__getattr__())变得不太方便。但是,名称修改算法有据可查,并且易于手动执行。

注 3:并非所有人都喜欢名称混淆。尝试在避免意外名称冲突的需求与高级调用者的潜在使用之间取得平衡。

解决方案 2:

双重__属性被更改为,_ClassName__method_name这使得它比 所暗示的语义隐私更加私密_method_name

从技术上来说,如果您真的愿意,您仍然可以得到它,但大概没有人会这样做,所以出于维护代码抽象的原因,该方法在这一点上可能是私有的。

class Parent(object):
    def _protected(self):
        pass

    def __private(self):
        print("Is it really private?")

class Child(Parent):
    def foo(self):
        self._protected()

    def bar(self):
        self.__private()

c = Child()
c._Parent__private()

这有额外的好处(或者有人会说是主要的好处),就是允许方法不与子类方法名称冲突。

解决方案 3:

通过声明数据成员为私有的:

__private()

你根本无法从课堂外部访问它

Python 支持一项称为名称修改的技术。

该特性将以两个下划线为前缀的类成员变为:

_className.memberName

如果你想访问它,Child()你可以使用:self._Parent__private()

解决方案 4:

PEP8还表示

仅对非公共方法和实例变量使用一个前导下划线。

为了避免与子类发生名称冲突,请使用两个前导下划线来调用 Python 的名称修改规则。

Python 将这些名称与类名混为一谈:如果class Foo有一个名为 的属性__a,则 无法访问它Foo.__a。(坚持的用户仍可以通过调用 获得访问权限Foo._Foo__a。)通常,仅应使用双前导下划线来避免与旨在子类化的类中的属性发生名称冲突。

按照惯例,你也应该远离_such_methods。我的意思是你应该把它们当作private

解决方案 5:

虽然这是一个老问题,但我遇到了它并找到了一个很好的解决方法。

在这种情况下,您在父类上命名了混乱,因为您想要模仿受保护的函数,但仍然希望在子类上以简单的方式访问该函数。

parent_class_private_func_list = [func for func in dir(Child) if func.startswith ('_Parent__')]

for parent_private_func in parent_class_private_func_list:
        setattr(self, parent_private_func.replace("_Parent__", "_Child"), getattr(self, parent_private_func))        

这个想法是手动将父类函数名替换为适合当前命名空间的函数名。在子类的 init 函数中添加此函数后,您可以轻松调用该函数。

self.__private()

解决方案 6:

据我所知,在第二种情况下,Python 执行“名称改编”,因此父类的 __private 方法的名称实际上是:

_Parent__private

而且你也不能以这种形式在孩子身上使用它

相关推荐
  政府信创国产化的10大政策解读一、信创国产化的背景与意义信创国产化,即信息技术应用创新国产化,是当前中国信息技术领域的一个重要发展方向。其核心在于通过自主研发和创新,实现信息技术应用的自主可控,减少对外部技术的依赖,并规避潜在的技术制裁和风险。随着全球信息技术竞争的加剧,以及某些国家对中国在科技领域的打压,信创国产化显...
工程项目管理   3998  
  为什么项目管理通常仍然耗时且低效?您是否还在反复更新电子表格、淹没在便利贴中并参加每周更新会议?这确实是耗费时间和精力。借助软件工具的帮助,您可以一目了然地全面了解您的项目。如今,国内外有足够多优秀的项目管理软件可以帮助您掌控每个项目。什么是项目管理软件?项目管理软件是广泛行业用于项目规划、资源分配和调度的软件。它使项...
项目管理软件   2749  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Freshdesk、ClickUp、nTask、Hubstaff、Plutio、Productive、Targa、Bonsai、Wrike。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在项目管理过程中面临着诸多痛点,如任务分配不...
项目管理系统   85  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Monday、TeamGantt、Filestage、Chanty、Visor、Smartsheet、Productive、Quire、Planview。在当今快速变化的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多项目经理和团队在管理复杂项目时,常...
开源项目管理工具   96  
  本文介绍了以下10款项目管理软件工具:禅道项目管理软件、Smartsheet、GanttPRO、Backlog、Visor、ResourceGuru、Productive、Xebrio、Hive、Quire。在当今快节奏的商业环境中,项目管理已成为企业成功的关键因素之一。然而,许多企业在选择项目管理工具时常常面临困惑:...
项目管理系统   83  
热门文章
项目管理软件有哪些?
曾咪二维码

扫码咨询,免费领取项目管理大礼包!

云禅道AD
禅道项目管理软件

云端的项目管理软件

尊享禅道项目软件收费版功能

无需维护,随时随地协同办公

内置subversion和git源码管理

每天备份,随时转为私有部署

免费试用