在 Python 中使用 类 对函数进行分组
Grouping Functions by Using Classes in Python
我已经成为 Python 科学程序员几年了,随着我的程序越来越大,我发现自己遇到了一个特定的问题。我是自学成才的,所以我从未接受过任何正式培训,也没有真正花时间在 Python "properly".
的 'conventions' 编码上
无论如何,就这一点而言,我发现自己总是创建一个 utils.py 文件来存储我的程序使用的所有已定义函数。然后我发现自己将这些功能分组到各自的目的中。我知道的一种分组方式当然是使用 类,但我不确定我的策略是否违背了 classes 实际应该用于什么。
假设我有一堆函数,它们的功能大致相同:
def add(a,b):
return a + b
def sub(a,b):
return a -b
def cap(string):
return string.title()
def lower(string):
return string.lower()
现在显然这4个函数可以看作是做两个不同的目的,一个是计算,另一个是格式化。这是逻辑告诉我要做的,但我必须解决它,因为我不想初始化对应于 class evertime.
的变量
class calc_funcs(object):
def __init__(self):
pass
@staticmethod
def add(a,b):
return a + b
@staticmethod
def sub(a, b):
return a - b
class format_funcs(object):
def __init__(self):
pass
@staticmethod
def cap(string):
return string.title()
@staticmethod
def lower(string):
return string.lower()
通过这种方式,我现在 'grouped' 将这些方法组合到一个很好的包中,可以根据它们在程序中的作用更快地找到所需的方法。
print calc_funcs.add(1,2)
print format_funcs.lower("Hello Bob")
不过话虽这么说,但我觉得这是一种非常 'unpython-y' 的做事方式,而且感觉很乱。我是在考虑正确的方法还是有其他方法?
我认为这样做是完美的 pythonic。这正是 staticmethod
构造函数的目的。
对于 python 约定,请参阅 PEP 8。
我不会为此使用 class
,我会使用 module
。仅由静态方法组成的 class 也让我觉得代码有味道。以下是使用模块执行此操作的方法:任何时候将代码粘贴到单独的文件中并将其导入另一个文件时,Python 都会将该代码粘贴到与文件同名的模块中。所以在你的情况下:
在mathutil.py
def add(a,b):
return a+b
def sub(a,b):
return a-b
在main.py
import mathutil
def main():
c = mathutil.add(a,b)
或者,如果您打算在很多地方使用 mathutil 并且不想每次都输入(和阅读)完整的模块名称,请提出一个标准缩写并在任何地方使用它:
在main.py
中,备用版本
import mathutil as mu
def main():
c = mu.add(a,b)
与您的方法相比,您将拥有更多文件,每个文件中的功能更少,但我认为以这种方式导航代码更容易。
顺便说一下,命名 files/modules 有一些 Python 约定:简称,全部小写,单词之间没有下划线。这不是我一开始做的,但我已经开始在我的代码中这样做,这让我更容易理解我使用过的其他人的模块的结构。
另一种方法是制作一个 util
包 并将您的功能拆分到该包内的不同模块中。包的基础知识:创建一个目录(其名称将是包名称)并在其中放入一个特殊文件,即 __init__.py
文件。这个可以包含代码,但是对于基本的包组织,它可以是一个空文件。
my_package/
__init__.py
module1.py/
modle2.py/
...
module3.py
假设您在工作目录中:
mkdir util
touch util/__init__.py
然后在您的 util
目录中,制作 calc_funcs.py
def add(a,b):
return a + b
def sub(a,b):
return a -b
和format_funcs.py
:
def cap(string):
return string.title()
def lower(string):
return string.lower()
现在,您可以从您的工作目录执行以下操作:
>>> from util import calc_funcs
>>> calc_funcs.add(1,3)
4
>>> from util.format_funcs import cap
>>> cap("the quick brown fox jumped over the lazy dog")
'The Quick Brown Fox Jumped Over The Lazy Dog'
编辑添加
但是请注意,如果我们重新启动解释器会话:
>>> import util
>>> util.format_funcs.cap("i should've been a book")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'util' has no attribute 'format_funcs'
这就是 __init__.py
的用途!
在__init__.py
中添加以下内容:
import util.calc_funcs, util.format_funcs
现在,再次重启解释器:
>>> import util
>>> util.calc_funcs.add('1','2')
'12'
>>> util.format_funcs.lower("I DON'T KNOW WHAT I'M YELLING ABOUT")
"i don't know what i'm yelling about"
耶!通过轻松导入,我们可以灵活地控制我们的命名空间!基本上,__init__.py
与 class 定义中的 __init__
方法起着类似的作用。
我已经成为 Python 科学程序员几年了,随着我的程序越来越大,我发现自己遇到了一个特定的问题。我是自学成才的,所以我从未接受过任何正式培训,也没有真正花时间在 Python "properly".
的 'conventions' 编码上无论如何,就这一点而言,我发现自己总是创建一个 utils.py 文件来存储我的程序使用的所有已定义函数。然后我发现自己将这些功能分组到各自的目的中。我知道的一种分组方式当然是使用 类,但我不确定我的策略是否违背了 classes 实际应该用于什么。
假设我有一堆函数,它们的功能大致相同:
def add(a,b):
return a + b
def sub(a,b):
return a -b
def cap(string):
return string.title()
def lower(string):
return string.lower()
现在显然这4个函数可以看作是做两个不同的目的,一个是计算,另一个是格式化。这是逻辑告诉我要做的,但我必须解决它,因为我不想初始化对应于 class evertime.
的变量class calc_funcs(object):
def __init__(self):
pass
@staticmethod
def add(a,b):
return a + b
@staticmethod
def sub(a, b):
return a - b
class format_funcs(object):
def __init__(self):
pass
@staticmethod
def cap(string):
return string.title()
@staticmethod
def lower(string):
return string.lower()
通过这种方式,我现在 'grouped' 将这些方法组合到一个很好的包中,可以根据它们在程序中的作用更快地找到所需的方法。
print calc_funcs.add(1,2)
print format_funcs.lower("Hello Bob")
不过话虽这么说,但我觉得这是一种非常 'unpython-y' 的做事方式,而且感觉很乱。我是在考虑正确的方法还是有其他方法?
我认为这样做是完美的 pythonic。这正是 staticmethod
构造函数的目的。
对于 python 约定,请参阅 PEP 8。
我不会为此使用 class
,我会使用 module
。仅由静态方法组成的 class 也让我觉得代码有味道。以下是使用模块执行此操作的方法:任何时候将代码粘贴到单独的文件中并将其导入另一个文件时,Python 都会将该代码粘贴到与文件同名的模块中。所以在你的情况下:
在mathutil.py
def add(a,b):
return a+b
def sub(a,b):
return a-b
在main.py
import mathutil
def main():
c = mathutil.add(a,b)
或者,如果您打算在很多地方使用 mathutil 并且不想每次都输入(和阅读)完整的模块名称,请提出一个标准缩写并在任何地方使用它:
在main.py
中,备用版本
import mathutil as mu
def main():
c = mu.add(a,b)
与您的方法相比,您将拥有更多文件,每个文件中的功能更少,但我认为以这种方式导航代码更容易。
顺便说一下,命名 files/modules 有一些 Python 约定:简称,全部小写,单词之间没有下划线。这不是我一开始做的,但我已经开始在我的代码中这样做,这让我更容易理解我使用过的其他人的模块的结构。
另一种方法是制作一个 util
包 并将您的功能拆分到该包内的不同模块中。包的基础知识:创建一个目录(其名称将是包名称)并在其中放入一个特殊文件,即 __init__.py
文件。这个可以包含代码,但是对于基本的包组织,它可以是一个空文件。
my_package/
__init__.py
module1.py/
modle2.py/
...
module3.py
假设您在工作目录中:
mkdir util
touch util/__init__.py
然后在您的 util
目录中,制作 calc_funcs.py
def add(a,b):
return a + b
def sub(a,b):
return a -b
和format_funcs.py
:
def cap(string):
return string.title()
def lower(string):
return string.lower()
现在,您可以从您的工作目录执行以下操作:
>>> from util import calc_funcs
>>> calc_funcs.add(1,3)
4
>>> from util.format_funcs import cap
>>> cap("the quick brown fox jumped over the lazy dog")
'The Quick Brown Fox Jumped Over The Lazy Dog'
编辑添加
但是请注意,如果我们重新启动解释器会话:
>>> import util
>>> util.format_funcs.cap("i should've been a book")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: module 'util' has no attribute 'format_funcs'
这就是 __init__.py
的用途!
在__init__.py
中添加以下内容:
import util.calc_funcs, util.format_funcs
现在,再次重启解释器:
>>> import util
>>> util.calc_funcs.add('1','2')
'12'
>>> util.format_funcs.lower("I DON'T KNOW WHAT I'M YELLING ABOUT")
"i don't know what i'm yelling about"
耶!通过轻松导入,我们可以灵活地控制我们的命名空间!基本上,__init__.py
与 class 定义中的 __init__
方法起着类似的作用。