Python套件,包,模块,TestCase和TestSuite的差异

时间:2012-03-25 11:16:24

标签: python unit-testing package suite

最好的猜测:

  • 方法 - def(self,maybeSomeVariables);实现某种目的的代码行
  • 功能 - 与方法相同但返回一些内容
  • 类 - 方法/功能组
  • 模块 - 脚本或一个或多个类。基本上是.py文件。
  • 包 - 包含模块的文件夹,以及其中的__init__.py文件。
  • 套装 - 按惯例,只是一个被大量抛出的词
  • TestCase - unittest相当于一个函数
  • TestSuite - unittest相当于一个Class(或Module?)

我的问题是:这是完全正确的吗?我是否错过了该列表中的任何分层构建块?

1 个答案:

答案 0 :(得分:1)

我觉得你正在处理实际上并不存在的差异。没有真正的等级制度。在python 中,一切都是一个对象。这不是一些抽象概念,但对于如何考虑使用python时创建的构造非常重要。对象只是一堆其他对象。无论你是否使用new-style classes,都有一点微妙之处,但如果没有其他正当理由,只需使用并假设新式的类。以下所有内容都假设是新式的。

如果一个对象是callable,你可以使用一对大括号的调用语法来调用它,其中包含参数:my_callable(arg1, arg2)。要可调用,对象需要实现__call__方法(或者在其C级类型定义中设置正确的字段)。

在python中,一个对象与type相关联。该类型描述了对象的构造方式。因此,例如,列表对象的类型为list,而函数对象的类型为function。类型本身属于type类型。您可以使用内置函数type()找到该类型。可以在python documentation中找到所有内置类型的列表。类型实际上是可调用对象,用于创建给定类型的实例。

是的,现在已经建立,给定对象的性质由它的类型定义。这描述了它包含的对象。回到你的问题然后:

首先,构成某个对象的一堆对象称为该对象的属性。这些属性可以是任何属性,但它们通常由方法和某种存储状态的方式组成(可能是intlist等类型。

functionfunction类型的对象。至关重要的是,这意味着它将__call__方法作为属性使其成为可调用的(__call__方法也是一个本身具有__call__方法的对象。它是__call__一路下来;)

python世界中的class可以被视为一种类型,但通常用于引用非内置类型。这些对象用于创建其他对象。您可以使用class关键字定义自己的类,并创建一个新样式的类,您必须从object(或其他一些新样式类)继承。继承时,您创建一个获取父类型的所有特征的类型,然后您可以覆盖您想要的位(并且可以覆盖您想要的任何位!)。当您通过调用它来实例化一个类(或更一般地,一个类型)时,将返回另一个由该类创建的对象(如何通过修改类对象以奇怪和疯狂的方式更改返回的对象)。 / p>

method是一种特殊类型的函数,使用属性表示法调用。也就是说,当它被创建时,会向该方法添加2个额外属性(记住它是一个对象!),称为im_selfim_funcim_self我将用几句话来描述。 im_func是实现该方法的函数。调用方法时,例如foo.my_method(10),这相当于调用foo.my_method.im_func(im_self, 10)。这就是为什么当你定义一个方法时,你用额外的第一个参数定义它,你似乎似乎没有使用它(如self)。

在定义类时编写一堆方法时,这些方法将成为未绑定的方法。当您创建该类的实例时,这些方法将成为绑定。调用绑定方法时,会为您添加im_self参数作为绑定方法所在的对象。您仍然可以调用类的未绑定方法,但是您需要显式添加类实例作为第一个参数:

class Foo(object):

    def bar(self):
        print self
        print self.bar
        print self.bar.im_self # prints the same as self

我们可以展示当我们调用bar方法的各种表现时会发生什么:

>>> a = Foo()
>>> a.bar()
<__main__.Foo object at 0x179b610>
<bound method Foo.bar of <__main__.Foo object at 0x179b610>>
<__main__.Foo object at 0x179b610>
>>> Foo.bar()
TypeError: unbound method bar() must be called with Foo instance as first argument (got nothing instead)
>>> Foo.bar(a)
<__main__.Foo object at 0x179b610>
<bound method Foo.bar of <__main__.Foo object at 0x179b610>>
<__main__.Foo object at 0x179b610>

将上述所有内容放在一起,我们可以按如下方式定义一个类:

class MyFoo(object):
    a = 10
    def bar(self):
        print self.a

这将生成一个具有2个属性的类:a(值为10的整数)和bar,这是一种未绑定的方法。我们可以看到MyFoo.a只有10个。

我们可以在运行时创建额外的属性,包括类方法和外部。请考虑以下事项:

class MyFoo(object):
    a = 10

    def __init__(self):
        self.b = 20

    def bar(self):
        print self.a
        print self.b

    def eep(self):
        print self.c

__init__只是在从类创建对象后立即调用的方法。

>>> foo = Foo()
>>> foo.bar()
10
20
>>> foo.eep()
AttributeError: 'MyFoo' object has no attribute 'c'
>>> foo.c = 30
>>> foo.eep()
30

此示例显示了在运行时向类实例添加属性的两种方法(即,在从其类创建对象之后)。

我希望你能看到,TestCase和TestSuite只是用于创建测试对象的类。除了它们碰巧有一些用于编写测试的有用功能之外,没有什么特别之处。您可以将它们子类化并覆盖它们的内容!

关于您的具体观点,方法和函数都可以返回他们想要的任何内容。

您对模块,包和套件的描述看起来很合理。请注意,模块也是对象!