如何将一个类的函数分成多个文件?
问题描述
我有一个主类,其中有一堆不同的函数。现在越来越难管理了。我希望能够将这些函数分离到单独的文件中,但我发现很难想出一个好方法来做到这一点。
以下是我到目前为止所做的工作:
文件main.py
import separate
class MainClass(object):
self.global_var_1 = ...
self.global_var_2 = ...
def func_1(self, x, y):
...
def func_2(self, z):
...
# tons of similar functions, and then the ones I moved out:
def long_func_1(self, a, b):
return separate.long_func_1(self, a, b)
文件parate.py
def long_func_1(obj, a, b):
if obj.global_var_1:
...
obj.func_2(z)
...
return ...
# Lots of other similar functions that use info from MainClass
我这样做是因为如果我这样做:
obj_1 = MainClass()
我希望能够:
obj_1.long_func_1(a, b)
而不是:
separate.long_func_1(obj_1, a, b)
我知道这看起来有点挑剔,但我希望几乎所有代码都以obj_1.
开头,所以没有念力。
有没有比我目前正在做的更好的解决方案?我当前设置的唯一问题是:
- 我必须更改函数的两个实例的参数
- 这似乎是不必要的重复
我知道这个问题已经被问了几次,但是我不太理解前面的答案和/或我认为这个解决方案并不能完全代表我所追求的目标。我对Python还很陌生,所以我很难弄清楚这一点。
解决方案
我是这样做的:
类(或组)实际上是一个完整的模块。您不必这样做,但是如果您要将一个类拆分到多个文件上,我认为这是"最干净的"(观点)。
定义在
__init__.py
中,方法按有意义的分组拆分成文件。方法文件只是一个带有函数的常规Python文件,除非您不能忘记‘self’作为第一个参数。这里可以有辅助方法,同时带
self
和不带。方法直接导入到类定义中。
假设我的类是一些合适的GUI(这实际上是我第一次这样做)。因此我的文件层次结构可能类似
mymodule/
__init__.py
_plotstuff.py
_fitstuff.py
_datastuff.py
所以Plot元素将有绘图方法,Fit元素包含Figing方法,而Data元素包含加载和处理数据的方法-您明白了这一点。按照惯例,我用_
标记这些文件,以表明这些文件实际上不能直接导入到模块之外的任何地方。例如,_plotsuff.py
可能如下所示:
def plot(self,x,y):
#body
def clear(self):
#body
等,现在重要的是文件__init__.py
:
class Fitter(object):
def __init__(self,whatever):
self.field1 = 0
self.field2 = whatever
# Imported methods
from ._plotstuff import plot, clear
from ._fitstuff import fit
from ._datastuff import load
# static methods need to be set
from ._static_example import something
something = staticmethod(something)
# Some more small functions
def printHi(self):
print("Hello world")
Tom Sawyer提到PEP-8建议将所有导入放在顶部,因此您可能希望将它们放在__init__
之前,但我更喜欢这样。我不得不说,我的Flake8检查器没有抱怨,所以这很可能是符合PEP-8的。
from ... import ...
对于隐藏一些您不希望通过类的对象访问的方法的"helper"函数特别有用。我通常也会将类的自定义异常放在不同的文件中,但是直接导入它们,这样就可以Fitter.myexception
访问它们。
如果此模块在您的路径中,则可以使用
访问您的类from mymodule import Fitter
f = Fitter()
f.load('somefile') # Imported method
f.plot() # Imported method
不完全直观,但也不太难。对于您的特定问题,简而言之就是您已经很接近了-只需将导入移到类中,然后使用
from separate import long_func_1
别忘了self
!
相关文章