如何设置Python项目?

时间:2010-12-03 20:46:45

标签: python class

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

我如何/在何处定义类和对象?

5 个答案:

答案 0 :(得分:8)

只是给你一个典型Python模块源代码的例子,这里有一些解释。这是一个名为“Dims.py”的文件。这不是整个文件,只是一些部分来了解发生了什么。

#!/usr/bin/env python

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

"""Library for dealing with lengths and locations."""

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

# Units
MM_BASIC = 1500000
MILS_BASIC = 38100
IN_BASIC = MILS_BASIC * 1000

在称为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
}

这些模块级变量的名称中包含前导下划线。这为他们提供了有限的“隐私权”,因为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]

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
    """

班级声明。请注意,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

这是初始值设定项。与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.""")

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

如果您拥有只读属性,则可以使用property作为装饰器来声明它。例如,如果上面的属性是只读的,我会写:

    @property
    def basic(self):
        """This returns the length in basic units."""
        return self._x

请注意,属性的名称是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)

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

    __rmul__ = __mul__

由于代码只是一个类似于其他任何值的值,因此您可以将一个方法的代码分配给另一个方法。该行告诉Python something * Length操作使用与Length * something相同的代码。 D on R epeat Y 我们自己。

现在声明了类,我可以回到模块代码。在这种情况下,如果此文件由其自身执行,我有一些代码要运行 ,而不是作为模块导入。所以我使用以下测试:

if __name__ == "__main__":

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

    import doctest
    doctest.testmod()

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

关于doctests的最后一点说明:它们很有用,但它们并不是最通用或全面的测试。对于那些,您需要阅读单元测试(unittest模块)。

答案 1 :(得分:3)

每个python源文件都是一个模块。没有“标题”文件。基本的想法是,当你导入“foo”时,它将从“foo.py”(或之前编译的版本)加载代码。然后,您可以通过说foo.whatever来访问foo模块中的内容。

在Python代码中安排事物似乎有两种方法。有些项目使用平面布局,其中所有模块都位于顶层。其他人使用层次结构。您可以通过导入“foo.bar.baz”导入foo / bar / baz.py。分层布局的大问题是在适当的目录中有__init__.py(它甚至可以是空的,但它应该存在)。

类的定义如下:

class MyClass(object):
    def __init__(self, x):
        self.x = x

    def printX(self):
        print self.x

创建实例:

z = MyObject(5)

答案 2 :(得分:0)

您可以以对您的应用程序最有意义的任何方式组织它。我不知道你在做什么,所以我无法确定最适合你的组织是什么,但是你可以在你认为合适的时候将它分开,然后输入你需要的东西。

您可以在任何文件中定义类,并且可以在脚本中定义任意数量的类(与Java不同)。没有正式的头文件(不像C或C ++),但您可以使用配置文件来存储有关连接到数据库的信息,无论如何,并使用configparser(标准库函数)来组织它们。

将相同的内容保存在同一个文件中是有意义的,因此如果您有GUI,则可能有一个用于该接口的文件,如果您有CLI,则可以将其保存在文件中。文件的组织方式不太重要,更重要的是如何将源组织成类和函数。

答案 3 :(得分:0)

这是寻找它的地方:http://docs.python.org/reference/

首先,编译并安装piphttp://pypi.python.org/pypi/pip。它就像Ubuntu的apt-get。您可以通过键入pip install package-name来通过终端运行它。它有一个包数据库,因此你可以很容易地安装/卸载它。

至于导入和“标题”文件,据我所知,如果你运行import foo,Python会在当前文件夹中查找foo.py。如果它不存在,它会查找egg(在Python模块目录中解压缩的文件夹)并导入它们。

至于定义类和对象,这是一个基本的例子:

class foo(foobar2): # I am extending a class, in this case 'foobar2'. I take no arguments.
  __init__(self, the, list, of, args = True): # Instead, the arguments get passed to me. This still lets you define a 'foo()' objects with three arguments, only you let '__init__' take them.
    self.var = 'foo'

  def bar(self, args):
    self.var = 'bar'

  def foobar(self):  # Even if you don't need arguments, never leave out the self argument. It's required for classes.
    print self.var

foobar = foo('the', 'class', 'args') # This is how you initialize me!

在Python Reference中阅读更多内容,但我唯一的建议是永远不会忘记类函数中的self参数。它将为您节省大量的调试麻烦......

祝你好运!

答案 4 :(得分:0)

Python程序没有固定的结构,但您可以以Django项目为例。 Django项目由一个settings.py模块组成,其中存储了全局设置(类似于具有数据库连接属性的示例)和可插拔应用程序。每个应用程序都有自己的models.py模块,该模块存储数据库模型,可能还有其他域特定对象。其余的都取决于你。

请注意,这些建议并非特定于Python。在C / C ++中,您可能使用了类似的结构并在XML中保留了设置。只需忘记标题并将设置放在.py文件中,就是这样。