我知道这已被问了好几次,但我不能理解以前的答案和/或我认为解决方案并不能代表我正在拍摄的内容。我还是Python的新手,所以我很难搞清楚这一点。
我有一个主要类,其中包含不同功能的TON。它变得越来越难以管理。我希望能够将这些功能分成一个单独的文件,但我发现很难找到一个好方法。
这是我到目前为止所做的:
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
我这样做是因为如果我这样做:
obj_1 = MainClass()
我希望能够做到:
obj_1.long_func_1(a, b)
而不是:
separate.long_func_1(obj_1, a, b)
我知道这似乎有点挑剔,但我想要的所有代码都以obj_1.
开头,所以不会产生混淆。
我目前正在做的是否有更好的解决方案?我目前设置的唯一问题是:
答案 0 :(得分:10)
我真的很惊讶这不是重复。我看到了一些类似的问题,我认为没有一个简洁的答案,所以这就是我如何做到的:
__init__.py
中,方法通过有意义的分组分割成文件。self
。 假设我的班级是一些适合的gui(这实际上是我第一次这样做)。所以我的文件层次结构可能类似于
mymodule/
__init__.py
_plotstuff.py
_fitstuff.py
_datastuff.py
因此,绘图方法将具有绘图方法,适合的东西包含拟合方法,数据包含用于加载和处理数据的方法 - 您明白了。按照惯例,我使用_
标记文件,以指示这些文件实际上并不打算直接导入模块外的任何位置。所以_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
#Some more small functions
def printHi(self):
print("Hello world")
#I think static methods have to be here
@staticmethod
def something(argumentIsNotSelf):
print('yay')
Tom Sawyer提到PEP-8建议将所有导入设置在顶部,因此您可能希望将它们放在__init__
之前,但我更喜欢这种方式。
注意from ... import ...
对于隐藏您不希望通过类对象访问的方法的某些“帮助”函数特别有用。我通常也会将类的自定义异常放在不同的文件中,但直接导入它们以便可以Fitter.myexception
访问它们。
如果此模块在您的路径中,那么您可以使用
访问您的班级from mymodule import Fitter
f = Fitter()
f.load('somefile') #Imported method
f.plot() #Imported method
不完全直观,但也不困难。针对您的特定问题的简短版本就是您的关闭 - 只需将导入移动到类中,然后使用
from separate import long_func_1
并且不要忘记您的self
!
答案 1 :(得分:1)
我使用发现的方法here 它显示了许多不同的方法,但是如果您滚动到最后,则首选方法是基本上与@Martin Pieter的建议相反,该建议的基类继承了那些类中的方法。
文件夹结构如下:
_DataStore/
__init__.py
DataStore.py
_DataStore.py
所以您的基类将是:
# DataStore.py
import _DataStore
class DataStore(_DataStore.Mixin): # Could inherit many more mixins
def __init__(self):
self._a = 1
self._b = 2
self._c = 3
def small_method(self):
return self._a
然后您的Mixin类:
# _DataStore.py
class Mixin:
def big_method(self):
return self._b
def huge_method(self):
return self._c
您的单独方法将位于其他适当命名的文件中,在本示例中,它只是_DataStore。
我很想听听其他人对这种方法的看法,我向工作中的人展示了这种方法,但他们对此感到害怕,但这似乎是一种将类拆分为多个文件的干净便捷的方法。
答案 2 :(得分:0)
这是@Martijn Pieters♦关于使用子类的注释的实现:
main.py
:
from separate import BaseClass
class MainClass(BaseClass):
def long_func_1(self, a, b):
if self.global_var_1:
...
self.func_2(z)
...
return ...
# Lots of other similar functions that use info from BaseClass
separate.py
:
class BaseClass(object):
# You almost always want to initialize instance variables in the `__init__` method.
def __init__(self):
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:
#
# Why are there "tons" of _similar_ functions?
# Remember that functions can be defined to take a
# variable number of/optional arguments, lists/tuples
# as arguments, dicts as arguments, etc.
from main import MainClass
m = MainClass()
m.func_1(1, 2)
....