Python 3.x Python3从父方法调用子属性

Python 3.x Python3从父方法调用子属性,python-3.x,inheritance,methods,attributes,parent,Python 3.x,Inheritance,Methods,Attributes,Parent,无法在父方法中调用子属性,测试如下: #!/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/Project

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

#!/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
返回

./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'
/test.py
回溯(最近一次呼叫最后一次):
文件“/test.py”,第17行,在
打印(instance.getPath())
文件“/test.py”,第6行,在getPath中
返回自我路径
AttributeError:“B”对象没有属性“\u A\u路径”

除非您知道为什么需要路径,否则不要使用路径<代码>\u路径足以将其标记为“专用”。但是,
A.getPath
不应试图返回未在
A
本身中定义的任何内容。相反,从
B.\uuuuu init\uuuuu
调用
A.\uuuuu init\uuuu
,以确保正确完成任何
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())
既然
\u path
已正确隔离到
A
,例如,如果您担心某个子类添加其自己的
\u path
属性,则可以切换回
\u 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))

除非您知道为什么需要路径,否则不要使用路径<代码>\u路径足以将其标记为“专用”。但是,
A.getPath
不应试图返回未在
A
本身中定义的任何内容。相反,从
B.\uuuuu init\uuuuu
调用
A.\uuuuu init\uuuu
,以确保正确完成任何
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())
既然
\u path
已正确隔离到
A
,例如,如果您担心某个子类添加其自己的
\u path
属性,则可以切换回
\u 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中的私有属性设计为允许每个类都有自己的私有变量副本,而不需要子类重写该变量。所以在B中,路径意味着路径,而在A中,路径意味着路径。这正是Python的工作原理。

由于您希望A能够访问_路径,因此不应使用双下划线。相反,您可以使用一个下划线,这是一种惯例,用于指示变量是私有的,而不实际强制执行它

#!/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

您之所以得到这个结果,是因为您使用的是私有属性。如果您使用非私有属性执行此操作,它将成功

Python中的私有属性设计为允许每个类都有自己的私有变量副本,而不需要子类重写该变量。所以在B中,路径意味着路径,而在A中,路径意味着路径。这正是Python的工作原理。

由于您希望A能够访问_路径,因此不应使用双下划线。相反,您可以使用一个下划线,这是一种惯例,用于指示变量是私有的,而不实际强制执行它

#!/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

在某些情况下,在中使用未定义的成员是完全有效的。这是“模板方法”设计模式。其思想是基类实现不变的部分,而子类实现不变的位。感谢您的回答。在某些情况下,在中使用未定义的成员是完全有效的。这是“模板方法”设计模式。其思想是基类实现不变的部分,而子类实现不变的位。谢谢你的回答谢谢你的回答