当前位置:  开发笔记 > 编程语言 > 正文

在python子类中创建一个私有方法

如何解决《在python子类中创建一个私有方法》经验,为你挑选了9个好方法。

是否可以在子类中将公共方法设为私有?我不希望扩展此类的其他类能够调用某些方法.这是一个例子:

class A:
    def __init__(self):
        #do something here

    def method(self):
        #some code here

class B(A):
    def __init__(self):
        A.__init__(self)
        #additional initialization goes here

    def method(self):
        #this overrides the method ( and possibly make it private here )

从这一点开始,我不希望任何从B扩展的类能够调用method.这可能吗 ?

编辑:这是一个"逻辑"的原因是我不希望用户以错误的顺序调用方法.



1> 小智..:

相反,在这个问题上流行的时尚,也正当的理由有公共,私有和保护成员之间的区别,无论你是在Python或更传统的面向对象的环境中工作.很多时候,你需要在某种对象专业化水平上为特别冗长的任务开发辅助方法.毋庸置疑,你真的不希望任何子类继承这些方法,因为它们在专门的上下文中没有任何意义,甚至不应该是可见的; 然而它们是可见的,并且它们削弱了标签完成,对象导航器和其他系统软件之类的功能,因为所有不同抽象级别的所有内容都变得扁平化并被抛在一起.请注意,这些编程辅助工具并非易事.如果你是一名学生,他们只是微不足道,因为你正在学习如何,他们喜欢做一百万次同样的事情.

Python历史上以这样的方式开发,由于意识形态惯性和兼容性问题,实现公共/私人区分变得越来越困难.这是明确的事实.每个人都要改变他们一直在做的事情,这将是一件非常令人头疼的问题.因此,我们现在有一百万名Python粉丝,所有人都阅读了相同的一两篇原创文章,明确地确定公共/私人的区别是"unpythonic".这些人由于缺乏批判性思维或对广泛传播的常规做法的公平性,立即利用这个机会吸收了一系列可预测的应用程序 - De Defensione Serpentis--我怀疑这不是来自合理选择的蟒蛇( pythonic方式)但忽略了他们选择不使用的其他语言,不熟练使用,或因工作而无法使用.

正如有人已经说过的,你可以用Python做的最好的效果是产生类似于私有方法的效果,就是在方法名前加上__(两个下划线).另一方面,实际上,唯一能实现的是在对象中插入一个变形的属性名称__dict__.例如,假设您有以下类定义:

class Dog(object):
    def __bark(self):
        print 'woof'

如果你跑dir(Dog()),你会看到一个叫做奇怪的成员_Dog__bark.实际上,存在这种技巧的唯一原因是为了规避我之前描述的问题:即防止超级方法的继承,重载和替换.

希望将来有一些标准化的私人方法实施,当人们意识到组织不需要获得单个细胞复制DNA的方法时,有意识的头脑需要不断弄清楚如何修复其组织和内脏器官.


一个好人。但这并不能使该思想变得不那么合理,即某个类或任何代码的用户而不是创建者最终应有权决定使用什么以及如何使用它。如果要警告用户,请在名称前添加一个下划线;此外,这还可以防止混乱的制表符完成。

2> Triptych..:

在Python中没有办法真正做到这一点.相反,它是非语音的.

正如Guido所说,我们都是在这里同意成年人.

这里是Python公开的一切背后哲学的一个很好的总结.



3> tzot..:

您可以使用单个或双下划线为方法和成员添加前缀.单个下划线暗示"请不要使用我,我应该只使用此类",并且双下划线指示Python编译器使用类名来破坏方法/成员名称; 只要类及其子类不具有相同的名称,方法/成员就可以被视为"私有".

但是,到目前为止,您的要求的解决方案是编写清晰的文档.如果您不希望用户以错误的顺序调用方法,请在文档中说明.

毕竟,即使是C++私有也不是私有的.例如,想想老技巧:

#define private public
#include 



4> Ali Afshar..:

我很惊讶没有人提到这一点,但在方法名称前加上一个下划线是将其标记为"私有"的正确方法.它当然不是私密的(正如其他答案中所解释的那样),但是你去了.

def _i_am_private(self):
    """If you call me from a subclass you are a naughty person!"""



5> S.Lott..:

Python作为源分发.私有方法的想法很有意义.

想要B通过隐私问题进行扩展的程序员查看B源代码,将源代码复制并粘贴method到子类中C.

你通过"隐私"获得了什么?您可以期待的最好的方法是让您的潜在客户挫败复制和粘贴.

在最坏的情况下,他们丢弃你的包裹,因为他们无法延长它.

是的,所有开源都以这种或那种方式扩展.您无法预见代码的所有内容和用途.当代码作为源分发时,很难防止将来使用.

请参阅如何保护Python代码?


编辑 "防止白痴"的代码.

首先,python在90%的时间内作为源分发.因此,任何下载,安装,然后拒绝阅读API指南并且无序调用方法的白痴仍有消息来找出问题所在.

我们有三类白痴.

拒绝阅读API指南(或浏览它并忽略相关部分)并尽管有文档而无法调用方法的人.你可以试着把某些东西私有化,但它无济于事,因为它们会做出别的错误 - 并抱怨它.[我不会说出名字,但我和那些似乎花费大量时间调用API不正确的人一起工作过.此外,你会在SO上看到这样的问题.]

您只能使用可以剪切和粘贴的工作代码示例来帮助他们.

那些被API迷惑并且以你能想象的方式调用这些方法的人(有些你不能这样做.)你可以尝试私有化,但他们永远不会得到API.

您只能通过提供工作代码示例来帮助他们; 即使这样,他们也会错误地剪切和粘贴它.

拒绝您的API并希望重写它以使其"白痴证明"的人.

您可以为他们提供工作代码示例,但他们不喜欢您的API并且会坚持重写它.他们会告诉你,你的API很疯狂,他们已经改进了.

你可以让这些人参加一场"白痴"的升级军备竞赛.你把它们放在一起的所有东西都拆开了.

在这一点上,隐私为您做了什么?有些人会拒绝理解它; 有些人对此感到困惑; 有些人想要解决它.

公众怎么样,让那些你称之为"白痴"的人从你的代码中学习?


信息隐藏是文档.通过从API中删除crud,API变得更容易学习.使用150,000种方法处理代码,其中没有一种是私有的,然后看看你是否仍然想要召唤人们白痴.
这是一个非常天真的答案.一个不好的假设是私有方法只是为了避免覆盖方法.但是,它通常用于API使用.私有方法将API缩减为重要方法; 为什么要向最终用户公开无用的辅助方法?如果有的话,应该支持受保护的方法.另一个问题(短视?)是,由于代码的公共性质,在升级库时,由于所有内容都是公开的,因此扩展类的名称冲突的可能性要大得多.封装和抽象是一件好事.
你的论点不是反对Python中的私有成员; 他们反对隐藏信息.为什么信息隐藏在C++和Java中有意义但在Python中却没有?
实际上,真正的问题是,*信息隐藏是否有用?*如果没有,C++和Java无缘无故地搞乱了.如果是,我认为,Python中缺少某些东西.
一般来说,Python教徒可以提供的最佳答案是"因为那不会是pythonic",或者"因为Guido会说...".但这些答案提出了问题.
@Daniel Holth:有文档化的API,还有"private"关键字.Python的名称以"_"开头,它们不是字面上的"私有",但不是文档化API的一部分.我从不说"白痴",因为我不同意任何其他程序员都是白痴.

6> joeforker..:

这可能是一个公平的近似值.词汇范围界定"救援":

#!/usr/bin/env python

class Foo(object):
    def __init__(self, name):
        self.name = name
        self.bar()

    def bar(self):
        def baz():
            print "I'm private"
            print self.name

        def quux():
            baz()

        self.quux = quux


if __name__ == "__main__":
    f = Foo("f")
    f.quux()

    g = Foo("g")
    g.quux()

    f.quux()

打印:

I'm private
f
I'm private
g
I'm private
f



7> joeforker..:

"一切都必须公开"支持者认为作者试图隐藏用户的有用API.这家伙不想违反毫无疑问的Python法则.他想使用一些方法来定义一个有用的API,并且他想使用其他方法来组织该API的实现.如果两者之间没有分离,那并不意味着作者不是白痴.这意味着作者实际上没有实际定义API.

在Python中,不是将属性或方法标记为私有,它们可以_作为弱"内部使用"指示符作为前缀,或者__作为稍微更强的指示符作为前缀.在模块中,名称可能以_相同的方式加上前缀,您也可以在一个名为变量的变量中放置一系列构成模块公共API的字符串__all__.

愚蠢的一致性是小脑袋的大人物.



8> 小智..:

将继承的方法从公共更改为私有会中断继承.具体来说,它打破了is-a关系.

想象一下餐厅课程采用开门公共方法(即晚餐时间,我们希望将前门标志从关闭翻转到打开).现在我们想要一个餐饮课,它将分享餐厅的许多实施细节(他们都需要厨师,厨房,餐具,食品供应商,甚至可能是服务员),但没有用餐区,前门或开门方法.从餐厅继承是一个错误!看起来您需要做的就是将开门方法改为私有,这样就没有人可以使用它了,但是"任何餐饮对象 - 餐厅"都是假的,因为餐厅公共界面的一部分是敞开的.最好通过添加一个新的基类来重构餐厅,然后餐厅和餐饮都来自它.

具有受保护或私有继承概念的语言仅支持实现继承的这种思想,但Python不是其中之一.(在很少的情况下,这些语言也没有用.)通常在寻求非公共继承时,包含(又称"有关系")是更好的路径,甚至可以使属性受到保护或私有.

Python法术受到单一领先下划线和私人双重领导下划线的保护,修改了Triptych答案中提到的"同意成人"哲学.您的类的"危险"属性和方法,例如可能导致数据丢失的属性和方法,应该是非公开的(无论是使其受到保护还是私有受其他因素的影响),公共方法用于提供更简单,更安全的界面.



9> Dana..:

要使方法类型为私有,您可以命名 - 修改一个方法,如下所示:

class Foo:
    def __blah():
        pass

class Bar(Foo):
    def callBlah():
        self.__blah() # will throw an exception

但是,如果他们真的想要,子类仍然可以通过内省找到你的方法.

但Python(通过深思熟虑的设计和选择)没有私人成员的概念.

推荐阅读
小色米虫_524
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有