在Python中使用类对函数进行分组

时间:2016-08-04 04:48:03

标签: python class conventions

我已经成为Python科学程序员已有几年了,随着程序越来越大,我发现自己遇到了一个特定的问题。我是自学成才,所以我从未接受过任何正式的培训,并且花了很多时间在'惯例上。用Python编写#34;正确"。

无论如何,到目前为止,我发现自己总是创建一个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 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()

这样我现在已经分组了#39;将这些方法组合成一个很好的包,可以根据它们在程序中的作用,更快地找到所需的方法。

print calc_funcs.add(1,2)
print format_funcs.lower("Hello Bob")

然而,话虽如此,我觉得这是一个非常不合时宜的事情。做事的方式,它只是感觉凌乱。我是否会以正确的方式思考这个问题,还是有其他方法?

3 个答案:

答案 0 :(得分:16)

另一种方法是创建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在类定义中扮演类似于__init__方法的角色。

答案 1 :(得分:4)

我不会使用class,我会使用module。一个只由静态方法组成的类也会让我感觉像代码一样。以下是如何使用模块执行此操作:只要将代码粘贴到单独的文件中并将其导入另一个文件,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)

与您的方法相比,每个文件中的文件功能更少,但我觉得以这种方式导航代码更容易。

顺便说一下,有一些用于命名文件/模块的Python约定:短名称,全部小写,单词之间没有下划线。这不是我开始做的事情,但我已经转而在我的代码中这样做,这使得更容易理解其他人的模块的结构我已经用过了。

答案 2 :(得分:1)

我认为这样做完全是pythonic。这正是staticmethod构造函数的目的。

对于python约定,请参阅PEP 8