Python简单的类理解

时间:2016-02-13 07:31:45

标签: python pass-by-reference python-2.x

我在练习基本python脚本时从网站上找到了以下代码。从下面的代码我能够理解类和实例以及第一个print语句。

但我不理解第二和第三个印刷语句背后使用的概念。如何将一个实例(在下面的代码polly中)作为参数传递给类的方法?我们可以在python中传递这样的选项吗?。

class Pet(object):

    def __init__(self, name, species):
        self.name = name
        self.species = species

    def getName(self):
        return self.name

    def getSpecies(self):
        return self.species

    def __str__(self):
        return "%s is a %s" % (self.name, self.species)

polly = Pet("Polly", "Parrot")

print "Polly is a %s" % polly.getSpecies()
Polly is a Parrot

print "Polly is a %s" % Pet.getSpecies(polly)
Polly is a Parrot

print "Polly is a %s" % Pet.getSpecies()
Traceback (most recent call last):
  File "", line 1, in
  TypeError: unbound method getSpecies() must be called with Pet instance as first argument (got nothing instead)

3 个答案:

答案 0 :(得分:1)

在Python中,一个类可以被视为一包属性。见下文:

>>> class Stuff:
...     pi = 3.14
...     def foo(x, y):
...         return x + y
...     bar = lambda s: s * 2
...
>>> Stuff.bar(4)
8
>>> Stuff.foo(5,6)
11
>>> Stuff.pi
3.14

在这个例子中,Stuff只是一堆随机对象。因此Stuff.bar指的是实际函数bar。类的实例具有不同的行为:访问函数时,它会自动转换为绑定方法。这意味着实例将自动作为第一个参数传递。

当您致电Pet.getSpecies(polly)时,polly将作为self参数传入。 self没有魔力,它只是另一个参数。当您访问polly.getSpecies并获得<bound method Polly.getSpecies of <__main__.Polly object at 0x7f946cd14b38>而不是<function Polly.getSpecies at 0x7f946cd1e048>时,就会感到神奇。

还有@classmethod装饰器,它接收类作为第一个参数而不是实例,并通过明确分隔类方法和实例方法使代码更容易理解。

答案 1 :(得分:1)

事实上,instance.instance_method()将在内部变为TheClass.instance_method(instance)self将引用实例本身。所以第一个和第二个版本彼此相等。

一个简单的例子:

def getSpeciesGlobal(some_object):  # a normal function
    return some_object.species

polly = Pet("Polly", "Parrot")
polly.species   # "Parrot"
getSpeciesGlobal(polly)   # "Parrot"
# if we assign this function to the class.
Pet.getSpeciesGlobal = getSpeciesGlobal
Pet.getSpeciesGlobal(polly)  # "Parrot"

# the original way in your question
polly.getSpecies()  # "Parrot"
Pet.getSpecies(polly)   # "Parrot"

答案 2 :(得分:0)

在第二个print语句中,polly作为self方法传递给class方法。这在第一个印刷声明中隐含地发生。 在第三个打印件上,调用类方法,但没有实际对象可以处理数据。