简体   繁体   English

从不同文件中的同一 class 访问 function

[英]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.我正在尝试从位于不同文件中的 class 中访问 function 。

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:在 _A 文件中:

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'这是我想做的,但我得到的却不能: AttributeError: 'TestClass' object has no attribute '__DoSomething'

How can I access the static method from TestClass within AFile?如何从 AFile 中的 TestClass 访问 static 方法?

You are calling a private method from outside its class declaration, and it happens that python is doing some transformations under the hood .您正在从其 class 声明之外调用私有方法,并且碰巧python 正在做一些转换

As explained in the link above, the private attributes and methods of a python class are modified under the form _ClassName__attributename .如上面链接中所述,python class 的私有属性和方法在_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保持方法私有,但使用从 python 生成的方法名称
  • Use protected methods to use in your secondary file.使用受保护的方法在您的辅助文件中使用。

The following files will show you both possibilities:以下文件将向您展示这两种可能性:

_AFile.py _A文件.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类文件.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.此类别中的名称,当在 class 定义的上下文中使用时,将被重写以使用损坏的形式来帮助避免基类和派生类的“私有”属性之间的名称冲突。 See section Identifiers (Names).请参阅标识符(名称)部分。

Fix使固定

Change __DoSomething to _DoSomething_DoSomething更改为__DoSomething

You are spreading the implementation of class TestClass into two files ClassFile.py and _AFile.py .您正在将 class TestClass的实现分散到两个文件ClassFile.py_AFile.py中。 In such a case you need to put __init__.py (empty file) inside the module.在这种情况下,您需要将__init__.py (空文件)放入模块中。

Fix使固定

Your directory structure should look like below您的目录结构应如下所示

mymodule
   --> __init__.py
   --> ClassFile.py
   --> _AFile.py

ClassFile.py类文件.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 _A文件.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: Output:

3
5
9

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM