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?

Add Comment
2 Answer(s)

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 
Add Comment

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 
Add Comment

Your Answer

By posting your answer, you agree to the privacy policy and terms of service.