Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 父类从子类调用私有属性_Python_Oop - Fatal编程技术网

Python 父类从子类调用私有属性

Python 父类从子类调用私有属性,python,oop,Python,Oop,在下面的示例中,最后一行B().show()没有调用适当版本的show函数。它应该调用子版本而不是父版本。我想我应该做一些类似于uuu class_method()的事情,但我想不出一个完整的答案 我当然可以覆盖B中的show函数,但这实际上意味着复制并粘贴show函数。这不优雅 ## version one ## class A(object): def method(self): print("hello") def show(self):

在下面的示例中,最后一行B().show()没有调用适当版本的show函数。它应该调用子版本而不是父版本。我想我应该做一些类似于uuu class_method()的事情,但我想不出一个完整的答案

我当然可以覆盖B中的show函数,但这实际上意味着复制并粘贴show函数。这不优雅

## version one ##
class A(object):

    def method(self):
        print("hello")

    def show(self):
        self.method()

class B(A):

    def method(self):
        print("goodbye")


A().show() ## print out hello
B().show() ## print out goodbye

## version two ##    
class A(object):

    def __method(self):
        print("hello")

    def show(self):
        self.__method()

class B(A):

    def __method(self):
        print("goodbye")


A().show() ## print out hello
B().show() ## print out hello

如果您用两个下划线开始一个方法名,它将使它只能从该类访问。考虑下面的例子:

class A():
    def __m(self):
        pass
    def m(self):
        print(self.__m)

A().m()  # <bound method A.__m of <__main__.A object at 0x10e0c1898>>
A().__m()  # AttributeError: 'A' object has no attribute '__m'
最重要的是:

'_A__m': <function A.__m at 0x10e0ab730>

要保留每个类的私有方法并能够访问它们,可以执行以下操作:

class A(object):

    def __method(self):
        print("hello")
    method = __method

    def show(self):
        self.method()


class B(A):

    def __method(self):
        print("goodbye")
    method = __method
输出:
这使私有方法成为公共的:
B()。method()
打印
再见
。是的,它为私有方法创建了一个别名;这个别名是公共的。您不能直接调用私有方法,因此,您可以(如果它有用的话)替换为
方法=\uu blah
\uu blah
作为B的其他私有方法,而不破坏客户端代码。为什么您要将一个方法声明为私有,然后提供一种从任何地方访问它的方法?这和不公开有什么不同?这是一个好问题@MoxieBall;我不会这样做;但是,在某些情况下,您可能需要修改类的行为,而不破坏客户端代码或子类的代码,正如我在前面的评论中所提到的。@ReblochonMasque我认为,如果有必要保持方法私有化的
\u方法
约定,真正的解决方案是,调用
\u方法
的每个方法也必须在B中重写。我刚刚添加了这个作为我的回答的补充。这里的问题是方法
A.show
无法访问私有
B.\uu方法
并调用
A.\uu方法
。正如建议的那样,您还必须重载
显示
。使用
\u方法
样式名称的确切目的是什么?我这样问是因为除了“不要那样做”之外,你的问题实际上没有“解决办法”。您几乎不应该使用名称弄乱,除非在代理或mixin类中有一个内部变量,您不希望意外地与其他未知类的变量发生冲突。我认为继承这个约定是有利的——我不同意()。用户可以看到,这只会使它变得更加困难(例如,请参见
dir(B)
)。@J.Lin我相信我在我的回答中已经非常清楚地概述了您的选择,但重要的是您绝对不应该使用
\u class\u方法
,如果您正试图优雅地做到这一点,那么最优雅的方式就是将
\u方法
公开。
class A(object):
    def __method(self):
        print("hello")
    def show(self):
        self.__method()

class B(A):
    def __method(self):
        print("goodbye")
    def show(self):
        self.__method()

A().show() ## print out hello
B().show() ## print out goodbye
class A(object):

    def __method(self):
        print("hello")
    method = __method

    def show(self):
        self.method()


class B(A):

    def __method(self):
        print("goodbye")
    method = __method
hello
goodbye