Python doesn't quite have the concept of private
functions. It does, however, treat class attributes whose names start with at least two underbars and end with at most one underbar a little specially - it mangles the names to make them slightly harder to access. In this example, you can see that the function __func2
has had its name mangled. It's still possible to access and call the function - but you have to make a special effort to do it, simply calling o.func2()
fails:
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$
So to answer the question you asked:
How do you correctly use private functions in Python?
The answer is: just like any other function, but you have to be aware of the mangled name.
Moving on to the question you wanted to ask:
AttributeError: matrix instance has no attribute '_matrix'
This is coming from line 154:
self._matrix.__loadVec(vec,res)
The error message is telling you that the object called self
is an instance of class matrix
; but it has no attribute called _matrix
. Referring to the __savetoMatrix
function above, it looks like the attribute is simply called matrix
- so you need to refer to it as self.matrix
("the attribute called matrix
of the object called self
).
This The __savetoMatrix
function references self.matrix
rather than self._matrix
.
However, there's a deeper problem here. Reading between the lines, it looks as though this code comes from a class called matrix
; and instances of the class have an attribute called matrix
. When you call self.matrix.__loadVec()
, you're calling the function called __loadvec()
which is bound to the attribute matrix
bound to the object called self
.
Even if this is what you wanted to do, this won't work because of name mangling as outlined above - assuming that the attribute called matrix
has class inner_matrix
, you'd have to call the function as self._matrix._inner_matrix__loadVec()
I think that what you're actually trying to do is call the method called __loadVec()
defined in class matrix
though. To do this, you just need to call self.__loadVec()
. Because it's a call to a function within the same class, you don't even need to worry about the name mangling - these functions are intended to be used inside the class, and the interpreter will handle the mangling for you.
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