Python中模块和类的区别
Posted
技术标签:
【中文标题】Python中模块和类的区别【英文标题】:Difference between Module and Class in Python 【发布时间】:2017-08-28 05:42:32 【问题描述】:我可以给模块中的变量赋值吗?如果是,类和模块有什么区别?
PS:我是一个 Java 人(以防它有助于解释)。谢谢。
【问题讨论】:
【参考方案1】:这就像一个概念:Python 中的模块 > 类 > 函数。这是一个在单元测试工具Pytest about Fixture Scope across Classes, Modules中使用这个想法的例子。
【讨论】:
【参考方案2】:在 python 世界中,module
是 package
内的 python
文件 (.py)。包是一个文件夹,其根目录中有__init__.py
。这是一种物理上(在文件和文件夹中)组织代码的方法。
另一方面,class
是一种抽象,它收集了data
(特征)和method
(行为)定义以表示特定类型的对象。这是一种逻辑组织代码的方法。
一个模块可以有零个或一个或多个类。一个类可以在一个或多个 .py 文件(模块)中实现。
但通常,我们可以将一组变量和函数组织到一个类定义中,或者只是简单地将它们放在一个 .py 文件中并称之为模块。
同样在系统设计中,您可以进行详细的逻辑建模,或者直接跳过它并跳入物理建模。但是对于非常复杂的系统,最好不要跳过逻辑建模。对于更简单的系统,请使用 KISS。
如何组织你的代码
这就是我决定在类或模块中组织代码的方式:
类应该是基于该蓝图创建(许多)对象实例的蓝图。此外,类可以有子类(继承)。
因此,如果我需要继承或(许多)实例化,我会在类定义(方法和属性)下收集函数和变量。
否则,我会保持简单和愚蠢(KISS)并使用模块。
一个坏类的好迹象(应该是一个模块):你可以用static methods and properties
重写你所有的object methods and properties
。
【讨论】:
【参考方案3】:我可以为模块中的变量赋值吗? 总之是的。
module
的概念是指可以导入的单个 Python 文件(通过导入,您可以访问该模块中定义的变量/方法/类)。
通常和package
这个概念一起讨论,__init__.py
是一个文件夹。一个包可以包含子包或模块,同时,类似于模块,可以在其__init__.py
中定义要导入的变量/方法/类。
在 Python 中拥有模块/包的目的有点类似于在 Java 中拥有包:包含和分类可重用代码,解决命名冲突等等。
此外,Python 还有一个名为module
的内置类,就像list
、tuple
、dict
(请注意,由于遗留原因,Python 内置类不遵循 CapWords 命名约定)。 module
实例代表导入的模块/包。
当您使用 import
语句导入模块(单个 Python 文件)或包(带有 __init__.py
的文件夹)时,通常
1. 将创建module
类的新实例
2. 你在那个导入的 Python 文件中定义的类/方法/变量将被添加为这个module
实例的属性(如果它是一个包,它将是__init__.py
中定义的类/方法/变量)添加)。
因此,由于它只是module
类的一个实例,你可以为该实例的属性赋值和其他类实例操作。
import math
print(type([1,2,3]))
print(type(math))
print(dir([1,2,3]))
print(dir(math))
控制台:
<class 'list'>
<class 'module'>
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
['__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'acos', 'acosh', 'asin', 'asinh', 'atan', 'atan2', 'atanh', 'ceil', 'copysign', 'cos', 'cosh', 'degrees', 'e', 'erf', 'erfc', 'exp', 'expm1', 'fabs', 'factorial', 'floor', 'fmod', 'frexp', 'fsum', 'gamma', 'gcd', 'hypot', 'inf', 'isclose', 'isfinite', 'isinf', 'isnan', 'ldexp', 'lgamma', 'log', 'log10', 'log1p', 'log2', 'modf', 'nan', 'pi', 'pow', 'radians', 'sin', 'sinh', 'sqrt', 'tan', 'tanh', 'tau', 'trunc']
【讨论】:
【参考方案4】:Python 中的类和模块之间存在巨大的差异。
类是允许您创建具有属性和绑定功能的实例的蓝图。类支持继承、元类和描述符。
模块不能做任何这些,模块本质上是内部module
类的单个实例,它们的所有全局变量都是module
实例上的属性。您可以根据需要操作这些属性(添加、删除和更新),但要考虑到这些属性仍然构成该模块中定义的所有代码的全局命名空间。
从 Java 的角度来看,类在这里并没有什么不同。然而,模块可以包含不止一个类;函数和任何其他 Python 表达式的结果也可以是模块中的全局变量。
所以作为一般性的指导方针:
使用类作为建模您的问题域的对象的蓝图。 使用模块将功能收集到逻辑单元中。然后将数据存储在对您的应用程序有意义的位置。全局状态进入模块(函数和类也是全局状态,在开始时加载)。其他所有内容都进入其他数据结构,包括类的实例。
【讨论】:
从 java 到 python 我一直在努力掌握一些概念,我一直试图将所有东西都与 java 联系起来。这对消除我的误解非常有帮助。【参考方案5】:模块:
模块是包含 Python 定义和语句的文件。
正如doc 所说。
因此,python 中的模块只是一种组织代码的方式,它包含 python 类或仅包含函数。
如果您在项目中需要这些类或函数,您只需import
他们。
例如,python 中的 math
模块只包含一堆函数,您只需调用那些需要的函数 (math.sin
)。
看看这个question。
另一方面,python 类类似于 java 类,只是结构方式略有不同。
【讨论】:
以上是关于Python中模块和类的区别的主要内容,如果未能解决你的问题,请参考以下文章