如何在 Python 中正确使用私有函数? [复制]

Posted

技术标签:

【中文标题】如何在 Python 中正确使用私有函数? [复制]【英文标题】:How do you correctly use private functions in Python? [duplicate] 【发布时间】:2013-08-05 00:55:24 【问题描述】:

我是 Python 新手,在涉及私有函数时遇到了一些问题。我想在公共方法中调用其中两个,只是为了使代码看起来更清晰,但我根本无法理解运行时错误显示的内容。以下是完整代码的问题部分:

def __loadVec(self,vec,res):
    for i in range(0,res.getRows()):
        for j in range(0,res.getColumns()):
            vec.append(self.matrix[i][j])
    return

def __savetoMatrix(self,vec,res):
    index = 0
    for i in range(0,res.getRows()):
        for j in range(0,res.getColumns()):
            self.matrix[i][j] = vec[index]
            index += 1
    return

def fmatrixSort(self,res):
    try:
        print "Sorting matrix information..."
        vec = []
        self._matrix.__loadVec(vec,res)
        vec.sort()
        self_matrix.__savetoMatrix(vec,res)
    except TypeError:
        print "TypeError in fmatrixSort"            
    return

我要做的是完全组织一个矩阵,使其以最低值开始并以最高值结束。

这是程序显示的错误:

Traceback (most recent call last):
  File "MatrixClass.py", line 211, in <module>
    main()
  File "MatrixClass.py", line 203, in main
    mat.fmatrixSort(res)
  File "MatrixClass.py", line 154, in fmatrixSort
    self._matrix.__loadVec(vec,res)
AttributeError: matrix instance has no attribute '_matrix'

我应该如何解决这个问题?

【问题讨论】:

不要在 Python 中使用 class-private __identifiers。它们存在的原因与 Java/C++ 中的私有成员完全不同,并且不能替代它们。 你的代码被破解了,self_matrix是什么;你的问题也不是因为__methods,而是缺少self._matrix属性! 【参考方案1】:

Python 没有private 函数的概念。但是,它确实会稍微特殊地处理名称以至少两个下划线开头并以最多一个下划线结尾的类属性 - 它会破坏名称以使它们更难访问。在此示例中,您可以看到函数 __func2 的名称已损坏。仍然可以访问和调用该函数 - 但您必须付出特别的努力才能做到这一点,只需调用 o.func2() 失败:

james@bodacious:tmp$cat test.py

class myclass:

    def func1(self):
        print "one"

    def __func2(self):
        print "two"

o = myclass()

print dir(o)

o._myclass__func2()
o.func2()
james@bodacious:tmp$python test.py
['__doc__', '__module__', '_myclass__func2', 'func1']
two
Traceback (most recent call last):
  File "test.py", line 15, in <module>
    o.func2()
AttributeError: myclass instance has no attribute 'func2'
james@bodacious:tmp$

所以回答你问的问题:

如何在 Python 中正确使用私有函数?

答案是:就像任何其他函数一样,但您必须注意名称错误。

继续你想问的问题:

AttributeError: matrix instance has no attribute '_matrix'

这是来自第 154 行:

self._matrix.__loadVec(vec,res)

错误信息告诉您名为self 的对象是matrix 类的实例;但它没有名为_matrix 的属性。参考上面的__savetoMatrix函数,看起来属性被简单地称为matrix-所以你需要将它称为self.matrix(“self对象的属性称为matrix)。

这个__savetoMatrix函数引用self.matrix而不是self._matrix

但是,这里有一个更深层次的问题。从字里行间看,这段代码似乎来自一个名为 matrix 的类;并且类的实例有一个名为matrix 的属性。当您调用self.matrix.__loadVec() 时,您调用的是名为__loadvec() 的函数,该函数绑定到绑定到名为self 的对象的属性matrix

即使这是您想要做的,这也不会起作用,因为如上所述的名称修改 - 假设名为 matrix 的属性具有类 inner_matrix,您必须将函数调用为 @ 987654346@

认为你实际上想要做的是调用在类matrix 中定义的名为__loadVec() 的方法。为此,您只需致电self.__loadVec()。因为它是对同一个类中的一个函数的调用,所以您甚至不必担心名称混淆 - 这些函数旨在在类内部使用,解释器将为您处理名称混淆。

james@bodacious:tmp$cat test.py

class myclass:

    def func1(self):
        print "one"

    def __func2(self):
        print "two"

    def func3(self):
        self.__func2()
        print "three"

o = myclass()
print dir(o)
o.func3()
james@bodacious:tmp$python test.py
['__doc__', '__module__', '_myclass__func2', 'func1', 'func3']
two
three

【讨论】:

谢谢詹姆斯,效果很好 您说“Python 没有私有函数的概念。”如果你停在那里,这将是一个更好的答案。 不同意;朱利安的根本问题与私人职能无关,这只是一种干扰,必须加以处理,这样我们才能解决真正的问题。【参考方案2】:

您在代码的多个部分中混淆了self.matrixself._matrixself_matrix。很可能,您的意思是self.matrixself._matrix,其他的都是拼写错误。此外,fmatrixSort 可能应该在 self 上调用 __loadVec__savetoMatrix,而不是当前正在执行的操作。

补充说明:

如果您没有要返回的值,则无需在函数末尾使用return。当执行到函数末尾时,函数会自动返回。

range可以通过3种方式调用:

range(stop)
range(start, stop)
range(start, stop, step)

如果您要从 0 开始范围,只需省略 start 参数并使用 1 个参数调用 range

【讨论】:

谢谢,我没有意识到我能做到这一点

以上是关于如何在 Python 中正确使用私有函数? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

如何在其他类/模块中正确导入/使用我在 Python 中构建的类和模块? [复制]

如何在 Swift 中创建私有函数? [复制]

如何在 Python 中创建多个构造函数? [复制]

如何在 Python 中使私有变量可访问? [复制]

在公共函数中使用私有类型的最佳方式是啥? [复制]

为啥我可以在复制构造函数中访问私有变量?