如何在Python中扩展(继承)一个模块?

7
我听说模块在Python中非常常见,我经常使用模块来构建我的代码并避免使用类。但现在我正在编写一个名为Formula的模块,它具有与Car模块相同的许多功能。我该如何处理呢?
  • 在两个模块中复制代码?
  • 将其转换为类?
  • 重构代码以添加第三个父模块Vehicle,并导入所需的方法和变量?
第三种方法看起来不错,唯一的缺点是某些变量是特定于一个模块的(例如top_speed),但是父模块Vehicle中的函数需要访问这些特定变量。

没有看到一些代码,很难提供建议(我怀疑,如果有一些代码,这更适合于http://codereview.stackexchange.com/)。然而,听起来像是一个基于类的解决方案适合这里;`Car` 是一个 Vehicle。您还可以从Car导入函数到Formula中。 - jonrsharpe
@jonrsharpe,我总是对试图让继承从现有的层次结构中脱颖而出,比如“汽车是一种交通工具”,持有相当怀疑的态度。现在我们已经有了几十年的经验,可以看到面向对象作为一种抽象设计方法的策略是有缺陷和无益的。继承应该关注你需要代码做什么,而不是抽象关系。 - Mike Graham
@MikeGraham 总的来说,这是公平的;我认为我们需要看到更多OP实现的细节,才能确定最佳方案。我根据他们的评论来判断,车辆似乎是汽车和公式的合理父类。 - jonrsharpe
这种情况下的一个有用需求是使用Swagger CodeGenerator。每次创建的模块swagger_client需要按原样替换,不做任何修改。然而,由于自动生成的模块并未涵盖所有情况,有时您需要扩展它,例如,您想扩展Configuration类以使self.host动态而非静态。但是,如果您只在另一个模块中扩展此类,则Swagger客户端模块将不知道您的扩展,因此您需要扩展整个模块并使用它。有意义吗? - George Pligoropoulos
5个回答

2

一个模块是一个实例,不是一个类,所以你不能像继承6一样从它继承。

如果你的东西有状态,你应该使用类而不是模块。

如果你有两个需要相同东西的模块,那么要么a)其中一个应该拥有它并且第二个应该使用第一个,要么b)它们都应该从第三个模块中获取它。

模块名称通常是小写的,因为大写/驼峰命名表示类。


1

模块有时可以用来实现单例,但它们并不是类的替代品。您只能导入该模块一次,而类可以有多个实例。

如果需要继承,请使用类。


2
使用模块作为单例确实被一些人使用,但这是一种反模式。将实例存储在某个地方更易于测试、更灵活、更易于维护——http://glyph.twistedmatrix.com/2007/07/functional-functions-and-python.html - Mike Graham

0
class Base():
    .....

class derived(Base):
    ......

但这是继承类...


0

我想从一个模块继承,然后我做到了:

import json

class custom_json(): pass

for i in json.__all__:
    setattr(custom_json, i, getattr(json, i))

至少它能工作。

如果您要覆盖某些属性,请使用它:

import json

class custom_json():
    def dump():
        pass

for i in json.__all__:
    if not hasattr(custom_json, i):
        setattr(custom_json, i, getattr(json, i))

-2

让我举个例子:

Base.py

import os
import sys
config = dict()
config['module_name'] = "some_xyz_thing"
config['description'] = "Implements xyz functionality"

Derived.py

from Base import config
config['module_name'] = "som_more_xyz_functionality"

这样你就可以在模块级别使用继承


@MikeGraham 喜欢吗?能解释一下吗?这只是一个“例子”。从来没有提到过它会像现在这样工作。 - Arunmu
2
Derived.py 中未定义 config。即使您改为使用 from Base import config,然后执行 config['module_name'] = "som_more_xyz_functionality",也会改变 Base.py 版本的值。更重要的缺陷是试图这样做,而不是使用最佳实践来解决真正的问题。(此外,您还有语法错误。) - Mike Graham
这就是所谓的覆盖。如果你想扩展基础模块,只需继续添加到配置字典中,最终你将拥有在基础和派生类中定义的属性。虽然,你已经正确指出了导入错误,需要修复它。 - Arunmu
2
它并没有覆盖原有的内容,只是改变了它们共享的字典。 - Mike Graham
酷啊,又被莫名其妙地点了个踩,甚至都没有等待 OP 的观点。 - Arunmu

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接