Accessing function from the same class in a different file
I am trying to access a function from within a class that is within a different file.
My layout is:
Directory -> ClassFile.py -> _AFile.py
in ClassFile:
class TestClass: from ._AFile import test_1, test_2, test_3 def __init__(self): def RunAllTests(self): self.test_1() self.test_2() self.test_3() @staticmethod def __DoSomething(a, b): return a + b
in _AFile:
def test_1(self): self.__DoSomething def test_2(self): self.__DoSomething def test_3(self): self.__DoSomething
This is what I want to do but cannot as I get: AttributeError: ‘TestClass’ object has no attribute ‘__DoSomething’
How can I access the static method from TestClass within AFile?
You are calling a private method from outside its class declaration, and it happens that python is doing some transformations under the hood.
As explained in the link above, the private attributes and methods of a python class are modified under the form _ClassName__attributename
. This is a protection to avoid collision with subclasses defining potentially the same attributes or methods.
As a result, to make your import work as you want, you have two possibilities:
- keep the method private, but use the generated method name from python
- Use protected methods to use in your secondary file.
The following files will show you both possibilities:
_AFile.py
def test_1(self): # Express which private method you want to use self._TestClass__DoSomething() def test_2(self): # Use a protected attribute only self._do_another_thing()
ClassFile.py
class TestClass: from _AFile import test_1, test_2 def __init__(self): pass def RunAllTests(self): self.test_1() self.test_2() @staticmethod def __DoSomething(): print("done something") @staticmethod def _do_another_thing(): print("done another thing")
Execution:
>>> from ClassFile import TestClass >>> TestClass().RunAllTests() done something done another thing
Methods which start with __
are class-private and they are mangled and so you cant access them when importing form a different file.
Official Docs:
__*
Class-private names. Names in this category, when used within the context of a class definition, are re-written to use a mangled form to help avoid name clashes between “private” attributes of base and derived classes. See section Identifiers (Names).
Fix
Change __DoSomething
to _DoSomething
You are spreading the implementation of class TestClass
into two files ClassFile.py
and _AFile.py
. In such a case you need to put __init__.py
(empty file) inside the module.
Fix
Your directory structure should look like below
mymodule --> __init__.py --> ClassFile.py --> _AFile.py
ClassFile.py
class TestClass: from ._AFile import test_1, test_2, test_3 def __init__(self): pass def RunAllTests(self): self.test_1() self.test_2() self.test_3() @staticmethod def _DoSomething(a, b): result = a+b print (result) return result
_AFile.py
def test_1(self): self._DoSomething(1,2) def test_2(self): self._DoSomething(2,3) def test_3(self): self._DoSomething(4,5)
Testing:
from mymodule.ClassFile import TestClass test = TestClass() test.RunAllTests()
Output:
3 5 9