如何将类的功能分成多个文件? [英] How can I separate functions of class into multiple files?
问题描述
我知道这已经被问过几次了,但我不太明白以前的答案和/或我认为该解决方案不能完全代表我的目标.我对 Python 还是很陌生,所以我很难弄清楚这一点.
I know this has been asked a couple of times, but I couldn't quite understand the previous answers and/or I don't think the solution quite represents what I'm shooting for. I'm still pretty new to Python, so I'm having a tough time figuring this out.
我有一个主类,其中包含大量不同的功能.越来越难管了.我希望能够将这些函数分离到一个单独的文件中,但我发现很难想出一个好的方法来做到这一点.
I have a main class that has a TON of different functions in it. It's getting hard to manage. I'd like to be able to separate those functions into a separate file, but I'm finding it hard to come up with a good way to do so.
这是我到目前为止所做的:
Here's what I've done so far:
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)
separate.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
我这样做是因为如果我这样做:
I do this because if I do:
obj_1 = MainClass()
我希望能够做到:
obj_1.long_func_1(a, b)
代替:
separate.long_func_1(obj_1, a, b)
我知道这看起来有点挑剔,但我希望几乎所有代码都以 obj_1.
开头,这样就不会造成混淆.
I know this seems kind of nit-picky, but I want just about all of the code to start with obj_1.
so there isn't confusion.
是否有比我目前正在做的更好的解决方案?我当前设置的唯一问题是:
Is there a better solution that what I'm currently doing? The only issues that I have with my current setup are:
- 我必须更改函数的两个实例的参数
- 这似乎是不必要的重复
推荐答案
我真的很惊讶这不是重复的.我看到了一些类似的问题,我认为没有一个简洁的答案,所以我是这样做的:
I'm actually surprised this isn't a duplicate. I saw some similar questions and I think there is nowhere a concise answer, so here is how I do it:
- 类(或一组)实际上是一个完整的模块.您不必这样做,但如果您将一个类拆分为多个文件,我认为这是最干净的"(意见).
- 定义在
__init__.py
中,方法通过有意义的分组被拆分成文件. - 方法文件只是一个带有函数的常规 python 文件,除非您不能忘记self"作为第一个参数.您可以在此处使用辅助方法,既可以使用
self
,也可以不使用. - 方法直接导入到类定义中.
- Class (or group of) is actually a full module. You don't have to do it this way, but if you're splitting a class on multiple files I think this is 'cleanest' (opinion).
- The definition is in
__init__.py
, methods are split into files by a meaningful grouping. - A method file is just a regular python file with functions, except you can't forget 'self' as a first argument. You can have auxiliary methods here, both taking
self
and not. - Methods are imported directly into the class definition.
假设我的类是一些合适的 gui(这实际上是我第一次这样做).所以我的文件层次结构可能看起来像
Suppose my class is some fitting gui (this is actually what I did this for first time). So my file hierarchy may look something like
mymodule/
__init__.py
_plotstuff.py
_fitstuff.py
_datastuff.py
因此,绘图内容将具有绘图方法,拟合内容包含拟合方法,数据内容包含加载和处理数据的方法-您明白了.按照惯例,我用 _
标记文件,以表明这些文件实际上并不打算直接导入模块外的任何地方.所以 _plotsuff.py
例如可能看起来像:
So plot stuff will have plotting methods, fit stuff contains fitting methods, and data stuff contains methods for loading and handling of data - you get the point. By convention I mark the files with a _
to indicate these really aren't meant to be imported directly anywhere outside the module. So _plotsuff.py
for example may look like:
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
from ._static_example import something
#Some more small functions
def printHi(self):
print("Hello world")
#static methods need to be set
somthing = staticmethod(something)
Tom Sawyer 提到 PEP-8 建议将所有导入放在顶部,因此您可能希望将它们放在 __init__
之前,但我更喜欢这种方式.我不得不说,我的 Flake8 检查器没有抱怨,所以这很可能符合 PEP-8.
Tom Sawyer mentions PEP-8 recommends putting all imports at the top, so you may wish to put them before __init__
, but I prefer it this way. I have to say, my Flake8 checker does not complain, so likely this is PEP-8 compliant.
请注意,from ... import ...
对于将某些帮助器"函数隐藏到您不想通过类的对象访问的方法中特别有用.我通常也会将类的自定义异常放在不同的文件中,但直接导入它们,以便它们可以作为 Fitter.myexception
访问.
Note the from ... import ...
is particularly useful to hide some 'helper' functions to your methods you don't want accessible through objects of the class. I usually also place the custom exceptions for the class in the different files, but import them directly so they can be accessed as Fitter.myexception
.
如果此模块在您的路径中,那么您可以使用
If this module is in your path then you can access your class with
from mymodule import Fitter
f = Fitter()
f.load('somefile') #Imported method
f.plot() #Imported method
不完全直观,但也不难.您的特定问题的简短版本是您的关闭 - 只需将导入移动到课程中,然后使用
Not completely intuitive, but not to difficult either. The short version for your specific problem was your were close - just move the import into the class, and use
from separate import long_func_1
不要忘记你的自我
!
这篇关于如何将类的功能分成多个文件?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!