如何将类的功能分成多个文件? [英] How can I separate functions of class into multiple files?

查看:35
本文介绍了如何将类的功能分成多个文件?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我知道这已经被问过几次了,但我不太明白以前的答案和/或我认为该解决方案不能完全代表我的目标.我对 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:

  1. 我必须更改函数的两个实例的参数
  2. 这似乎是不必要的重复

推荐答案

我真的很惊讶这不是重复的.我看到了一些类似的问题,我认为没有一个简洁的答案,所以我是这样做的:

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:

  1. 类(或一组)实际上是一个完整的模块.您不必这样做,但如果您将一个类拆分为多个文件,我认为这是最干净的"(意见).
  2. 定义在__init__.py中,方法通过有意义的分组被拆分成文件.
  3. 方法文件只是一个带有函数的常规 python 文件,除非您不能忘记self"作为第一个参数.您可以在此处使用辅助方法,既可以使用 self,也可以不使用.
  4. 方法直接导入到类定义中.
  1. 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).
  2. The definition is in __init__.py, methods are split into files by a meaningful grouping.
  3. 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.
  4. 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆