1

我是 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'

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

4

2 回答 2

4

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是 class 的实例matrix;但它没有名为_matrix. 参考__savetoMatrix上面的函数,看起来属性被简单地调用了matrix——所以你需要将它称为self.matrix(“被调用matrix对象的属性被调用self)。

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

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

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

认为你实际上想要做的是调用__loadVec()在类中定义的方法matrix。为此,您只需调用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
于 2013-08-04T02:45:11.073 回答
2

您在代码的几个部分中混合了self.matrixself._matrix和。self_matrix最有可能的是,您的意思是self.matrixor self._matrix,而其他的则是拼写错误。此外,fmatrixSort可能应该调用__loadVec__savetoMatrix打开self而不是当前正在执行的操作。

补充说明:

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

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

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

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

于 2013-08-04T02:25:40.490 回答