如何设置Python项目?

Sha*_*oon 1 python class

我正在做一些繁重的命令行东西(不是基于网络的)并且是Python的新手,所以我想知道如何设置我的文件/文件夹/等.是否有"标题"文件,我可以保留所有数据库连接的东西?

如何/在哪里定义类和对象?

Mik*_*one 8

只是为了举例说明一个典型的Python模块的源代码,这里有一些解释.这是一个名为"Dims.py"的文件.这不是整个文件,只是一些部分来了解发生了什么.

#!/usr/bin/env python
Run Code Online (Sandbox Code Playgroud)

这是告诉shell如何执行此文件的标准第一行.说/usr/bin/env python而不是/usr/bin/python告诉shell通过用户的PATH找到Python; 期望的Python可能在~/bin/usr/local/bin.

"""Library for dealing with lengths and locations."""
Run Code Online (Sandbox Code Playgroud)

如果文件中的第一件事是字符串,那么它就是模块的文档字符串.docstring是一个在项目开始后立即出现的字符串,可以通过其__doc__属性访问.在这种情况下,由于它是模块的docstring,如果用户导入此文件import Dims,Dims.__doc__则将返回此字符串.

# Units
MM_BASIC = 1500000
MILS_BASIC = 38100
IN_BASIC = MILS_BASIC * 1000
Run Code Online (Sandbox Code Playgroud)

在称为PEP(Python Enhancement Proposal)8的文档中,有许多关于格式化和命名约定的良好指南.这些是模块级变量(实际上是常量),所以它们用下划线全部写成.不,我不遵守所有规则; 旧习难改.由于你刚刚开始新生,除非你不能,否则请遵循PEP 8.

_SCALING = 1
_SCALES = {
    mm_basic: MM_BASIC,
    "mm": MM_BASIC,
    mils_basic: MILS_BASIC,
    "mil": MILS_BASIC,
    "mils": MILS_BASIC,
    "basic": 1,
    1: 1
}
Run Code Online (Sandbox Code Playgroud)

这些模块级变量在其名称中具有前导下划线.这给了他们有限的"隐私",因为import Dims这不会让你访问Dims._SCALING.但是,如果你需要弄乱它,你可以明确地说出类似的东西import Dims._SCALING as scaling.

def UnitsToScale(units=None):
    """Scales the given units to the current scaling."""
    if units is None:
        return _SCALING
    elif units not in _SCALES:
        raise ValueError("unrecognized units: '%s'." % units)
    return _SCALES[units]
Run Code Online (Sandbox Code Playgroud)

UnitsToScale是一个模块级函数.请注意docstring以及默认值和异常的使用.=默认值声明周围没有空格.

class Length(object):
    """A length.  Makes unit conversions easier.

    The basic, mm, and mils properties can be used to get or set the length 
    in the desired units.
    >>> x = Length(mils=1000)
    >>> x.mils
    1000.0
    >>> x.mm
    25.399999999999999
    >>> x.basic
    38100000L
    >>> x.mils = 100
    >>> x.mm
    2.54
    """
Run Code Online (Sandbox Code Playgroud)

类声明.请注意,docstring中包含的内容类似于Python命令行命令.这些护理称为doctests,因为它们是docstring中的测试代码.稍后会详细介绍.

    def __init__(self, unscaled=0, basic=None, mm=None, mils=None, units=None):
        """Constructs a Length.

        Default contructor creates a length of 0.
        >>> Length()
        Length(basic=0)

        Length(<float>) or Length(<string>) creates a length with the given 
        value at the current scale factor.
        >>> Length(1500)
        Length(basic=1500)
        >>> Length("1500")
        Length(basic=1500)
        """

        # Straight copy
        if isinstance(unscaled, Length):
            self._x = unscaled._x
            return

        # rest omitted
Run Code Online (Sandbox Code Playgroud)

这是初始化程序.与C++不同,您只能获得一个,但您可以使用默认参数使其看起来像几个不同的构造函数可用.

    def _GetBasic(self): return self._x
    def _SetBasic(self, x): self._x = x
    basic = property(_GetBasic, _SetBasic, doc="""
        This returns the length in basic units.""")
Run Code Online (Sandbox Code Playgroud)

这是一处房产.它允许您使用与访问任何其他数据成员时相同的语法来获取getter/setter函数,在这种情况下,myLength.basic = 10执行相同的操作myLength._SetBasic(10).因为你可以做到这一点,你应该不会写的getter/setter功能默认情况下为您的数据成员.只需直接对数据成员进行操作即可.如果以后需要getter/setter函数,可以将数据成员转换为属性,模块的用户无需更改其代码.请注意,docstring位于属性上,而不是getter/setter函数.

如果您有一个属性只读,你可以使用property作为装饰声明它.例如,如果上面的属性是只读的,我会写:

    @property
    def basic(self):
        """This returns the length in basic units."""
        return self._x
Run Code Online (Sandbox Code Playgroud)

请注意,属性的名称是getter方法的名称.您还可以使用装饰器在Python 2.6或更高版本中声明setter方法.

    def __mul__(self, other):
        """Multiplies a Length by a scalar.

        >>> Length(10)*10
        Length(basic=100)
        >>> 10*Length(10)
        Length(basic=100)
        """
        if type(other) not in _NumericTypes:
            return NotImplemented
        return Length(basic=self._x * other)
Run Code Online (Sandbox Code Playgroud)

这会覆盖*操作员.请注意,您可以返回特殊值NotImplemented以告知Python此操作未实现(在这种情况下,如果您尝试乘以非字符串类型的非数字类型).

    __rmul__ = __mul__
Run Code Online (Sandbox Code Playgroud)

由于代码只是一个类似于其他任何值的值,因此您可以将一个方法的代码分配给另一个方法.这一行告诉Python该something * Length操作使用相同的代码Length * something. d on't ř EPEAT ÿ我们自己.

现在声明了类,我可以回到模块代码.在这种情况下,我有一些代码,我想在这个文件本身执行时运行,而不是作为模块导入.所以我使用以下测试:

if __name__ == "__main__":
Run Code Online (Sandbox Code Playgroud)

然后if只有在直接运行时才会执行代码.在这个文件中,我有代码:

    import doctest
    doctest.testmod()
Run Code Online (Sandbox Code Playgroud)

这将遍历模块中的所有文档字符串,并查找看起来像Python提示后面带有命令的行.假设以下行是命令的输出.如果命令输出其他内容,则认为测试失败并打印实际输出.阅读doctest模块文档以获取所有详细信息.

最后一个关于doctests的注释:它们很有用,但它们并不是最通用或最全面的测试.对于那些,您需要阅读unittests(unittest模块).