【问题标题】:What is the proper way to split a python module into submodules? [closed]将python模块拆分为子模块的正确方法是什么? [关闭]
【发布时间】:2013-12-11 23:32:01
【问题描述】:

我在 python 中的 gitlab API 库中工作。它最初是作为一个宠物项目来了解更多关于模块的,所以一开始我没有考虑它,而是开始编写模块目录内的 __init__.py 中的所有代码。

当然,现在它已经增长了,我可以看到组织很差,一个类有很多方法,测试变得困难,检查代码很混乱,因为那里有很多.

所以我想把它分成几个子模块,你知道典型的 from X import Y 所以代码更具可读性、可测试性、更小,但我发现我完全不知道如何实现它,因为我有很多共享变量等在整个类中,所有方法都使用类变量......

那么,有没有关于使用“子模块”创建 python 模块的好文档?如何在类之间共享对象变量?例如,我应该检查哪些明确的模块在一个子模块上登录而在另一个子模块上具有功能?

干杯!

【问题讨论】:

  • 我认为这个问题不能以目前的形式回答。作为一般提示,首先重写您的函数,使它们没有外部依赖项(共享变量)。对您更有帮助的是提取代码中最有问题的部分并要求code review
  • @thg435 但是如果他们完全依赖他人呢?比方说,你有一个包,它有一个模块登录和一个模块 dosomething。如果 dosomething 模块需要登录模块成功以便用户生成一个将在 dosomething.getsomething() 中使用的令牌怎么办?
  • Itxaka 那么你没有成功拆分代码。 dosomething 只需要一个令牌。它不在乎它来自哪里。它只需要“成为一个令牌”。这意味着它有 token.valid() 例如。任何尊重界面的东西都有效。这样,您可以测试需要令牌的东西,而无需首先真正进行身份验证。
  • @Itxaka 一​​个模块可以依赖其他模块来实现它们的特定功能。这就是你首先要模块化代码的原因:以合理的方式划分职责,并且能够在不同的地方重用功能,而不必多次实现它。但是,您不应该修改来自不同函数的相同变量。

标签: python module


【解决方案1】:

这个问题已经被问了很多,而这种问题的问题是它会相当主观(充其量)。当然有很多最佳实践,例如:

  • 将功能逻辑分组到模块中
  • 让您的模块保持简洁而不是过于复杂
  • 设计合理的 API

等等……

如果觉得它令人困惑、难以使用,那么其他人可能也会如此。 在您的同事和朋友身上测试您的 API 和设计。了解他们的看法 感觉不能使用你的图书馆。

一些有用的参考资料:

【讨论】:

  • 感谢所有链接,我会看看它们
【解决方案2】:

通常这被称为“重构”。如果您寻找的话,那里有很多优秀的 Python 和通用计算机科学文献。

根据您的描述,听起来您需要停止直接使用存储在类中的数据并开始使用成员函数进行访问。

class A(object):
    def __init__(self, value):
        self.value = value

a = A(1)
print a.value
a.value = 5
print a.value

看看我是如何直接修改值的?这可能导致代码中的各种假设。您最好使用方法来检索值并进行更改。注意,无意识的 getFoo/setFoo 也很糟糕。尝试让你的方法暴露行为而不是扭曲的旋钮。

class A(object):
    def __init__(self, value):
        self.value = value

    def is_safe(self):
        if value > 10:
            return False
        return True

    def increase_value(self, increment):
        if increment <= 0:
            raise ValueError("only positive increments are allowed")
        self.value += increment

看看逻辑是如何自包含的?我们从不希望 A 的实例变小,所以我们只允许增量并命名函数增加来表示这一点。 setValue 不知道是什么或为什么。

对于模块和子模块,将匹配的东西组合在一起。 “匹配”是基于你自己代码的需要。所有的用户功能?所有的数据库功能?将东西放入模块允许插入具有相同公开 API 的不同模块的可能性。考虑来自 SQL DB 或本地文本文件的身份验证。

【讨论】:

  • 感谢您的回答
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-04-09
  • 2012-05-14
相关资源
最近更新 更多