python 3 从父方法调用子属性

python 3 Call child attribute from parent method

无法在父方法中调用子属性,测试如下:

#!/usr/bin/env python3

class A():
    def getPath(self):
        return self.__path

class B(A):

    def __init__( self, name, path):
        self.__name = name
        self.__path = path

instance = B('test', '/home/test/Projects')

print(instance.getPath())

运行 python 测试文件 $ ./test.py returns

./test.py 
Traceback (most recent call last):
  File "./test.py", line 17, in <module>
    print(instance.getPath())
  File "./test.py", line 6, in getPath
    return self.__path
AttributeError: 'B' object has no attribute '_A__path'

除非您知道为什么需要它,否则不要使用 __path_path 足以将其标记为 "private"。但是,A.getPath 不应尝试 return 任何未在 A 本身中定义的内容。相反,从 B.__init__ 调用 A.__init__ 以确保正确完成任何 A 特定的初始化:

class A:
    def __init__(self, path):
        self._path = path

    def get_path(self):
        return self._path

class B(A):

    def __init__(self, name, path):
        super().__init__(path)
        self._name = name

instance = B('test', '/home/test/Projects')

print(instance.get_path())

现在 _path 已正确隔离到 A,您 可以 切换回 __path,例如,如果您担心关于 child class 添加自己的 _path 属性。

class A:
    def __init__(self, path):
        self.__path = path

    def get_path(self):
        return self.__path

class B(A):
    def __init__(self, name, path):
        super().__init__(path)
        self._name = name
        self._path = "foo"

 instance = B('test', '/home/test/Projects')

 print("{}, not {}".format(instance.get_path(), instance._path))

您收到此信息是因为您使用的是私有属性。如果您使用非私有属性执行此操作,它将成功。

Python 中的私有属性旨在允许每个 class 拥有自己的变量私有副本,而该变量不会被 subclasses 覆盖。所以在B中,__path表示_B__path,在A中,__path表示__A_path。这正是 Python 旨在工作的方式。 https://docs.python.org/3/tutorial/classes.html#tut-private

既然要A访问__path,就不要用双下划线。相反,您可以使用单个下划线,这是一种约定,表示变量是私有的,而无需实际强制执行。

#!/usr/bin/env python3

class A():
    def getPath(self):
        return self._path

class B(A):

    def __init__( self, name, path):
        self.__name = name
        self._path = path

instance = B('test', '/home/test/Projects')

print(instance.getPath())

$ ./test.py
/home/test/Projects