14 python file object decorator
我知道这已被问过几次,但我不能完全理解以前的答案和/或我认为解决方案并不能代表我正在拍摄的内容.我仍然是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)
Run Code Online (Sandbox Code Playgroud)
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
Run Code Online (Sandbox Code Playgroud)
我这样做是因为如果我这样做:
obj_1 = MainClass()
我希望能够做到:
obj_1.long_func_1(a, b)
代替:
separate.long_func_1(obj_1, a, b)
我知道这似乎有点挑剔,但我想要开始的所有代码,obj_1.所以没有混乱.
有没有比我目前正在做的更好的解决方案?我目前设置的唯一问题是:
kab*_*nus 22
我真的很惊讶这不是重复.我看到了一些类似的问题,我认为没有一个简洁的答案,所以这就是我如何做到的:
__init__.py,方法被分成具有有意义分组的文件.假设我的班级有些适合gui(这实际上是我第一次这样做的).所以我的文件层次结构可能看起来像
mymodule/
__init__.py
_plotstuff.py
_fitstuff.py
_datastuff.py
Run Code Online (Sandbox Code Playgroud)
因此,绘图方法将有绘图方法,拟合东西拟合方法,数据填充和数据处理 - 你明白了.按照惯例,我用a标记文件,self表明这些文件实际上并不是要直接导入模块外的任何地方.所以_例如可能看起来像:
def plot(self,x,y):
#body
def clear(self):
#body
Run Code Online (Sandbox Code Playgroud)
等等现在重要的是_plotsuff.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')
Run Code Online (Sandbox Code Playgroud)
请注意,__init__.py对于您不希望通过类的对象访问的方法隐藏一些"帮助"函数特别有用.我通常也会将类的自定义异常放在不同的文件中,但是直接导入它们以便可以将它们作为访问__init__.
如果此模块在您的路径中,那么您可以访问您的课程
from mymodule import Fitter
f = Fitter()
f.load('somefile') #Imported method
f.plot() #Imported method
Run Code Online (Sandbox Code Playgroud)
不完全直观,但也不困难.针对您的特定问题的简短版本是您的关闭 - 只需将导入移动到类中,然后使用
from separate import long_func_1
Run Code Online (Sandbox Code Playgroud)
别忘了你from ... import ...!
Jef*_*ton 10
我使用我在这里找到的方法 它显示了许多不同的方法,但是如果您向下滚动到最后,首选方法基本上是与@Martin Pieter 的建议相反的方向,该建议具有一个继承其他类的基类与您的方法在那些课上。
所以文件夹结构类似于:
_DataStore/
__init__.py
DataStore.py
_DataStore.py
Run Code Online (Sandbox Code Playgroud)
所以你的基类将是:
# 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
Run Code Online (Sandbox Code Playgroud)
然后你的 Mixin 类:
# _DataStore.py
class Mixin:
def big_method(self):
return self._b
def huge_method(self):
return self._c
Run Code Online (Sandbox Code Playgroud)
您的单独方法将位于其他适当命名的文件中,在此示例中它只是 _DataStore。
我很想听听其他人对这种方法的看法,我向工作中的某个人展示了它,他们被它吓到了,但这似乎是将一个类分成多个文件的一种干净而简单的方法。
以下是Martijn Pieters 使用子类的注释的实现:
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
Run Code Online (Sandbox Code Playgroud)
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.
Run Code Online (Sandbox Code Playgroud)
from main import MainClass
m = MainClass()
m.func_1(1, 2)
....
Run Code Online (Sandbox Code Playgroud)