简体   繁体   English

Python简单类理解

[英]Python simple class understanding

I found the below code from a website while practicing basic python scripting. 我在练习基本的python脚本时从网站上找到了以下代码。 From the below code I was able to understand the class and instance and first print statement. 从下面的代码中,我能够理解类和实例以及第一个打印语句。

But I do not understand the concept used behind second and third print statement. 但是我不理解第二和第三印刷声明后面使用的概念。 How can an instance(in the below code polly ) can be passed as an argument to a class's method? 如何将实例(在下面的代码polly )作为参数传递给类的方法? Is there any option in python that we can pass this like that?. 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)

In Python, a class can be treated as a bag of properties. 在Python中,类可以视为属性包。 See below: 见下文:

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

In this example, Stuff is just a bunch of random objects. 在此示例中, Stuff只是一堆随机对象。 So Stuff.bar refers to the actual function bar . 因此Stuff.bar是指实际的功能bar Instances of a class have a different behaviour: When a function is accessed, it automatically gets converted to a bound method. 类的实例具有不同的行为:访问函数时,它会自动转换为绑定方法。 This means that the instance is automatically passed as the first argument. 这意味着实例将作为第一个参数自动传递。

When you call Pet.getSpecies(polly) , polly will be passed in as the self parameter. 当您调用Pet.getSpecies(polly)polly将作为self参数传入。 There's no magic to self , it's just another parameter. self没有魔力,这只是另一个参数。 The magic is when you access polly.getSpecies and get a <bound method Polly.getSpecies of <__main__.Polly object at 0x7f946cd14b38> instead of a <function Polly.getSpecies at 0x7f946cd1e048> . 当您访问polly.getSpecies并获得<bound method Polly.getSpecies of <__main__.Polly object at 0x7f946cd14b38><bound method Polly.getSpecies of <__main__.Polly object at 0x7f946cd14b38>而不是<function Polly.getSpecies at 0x7f946cd1e048>

There's also the @classmethod decorator, which receives the class as the first argument instead of the instance, as well as making code easier to understand by clearly delimiting class methods and instance methods. 还有@classmethod装饰器,它接收类而不是实例作为第一个参数,并通过清楚地划分类方法和实例方法使代码更易于理解。

In fact, instance.instance_method() will turn into TheClass.instance_method(instance) internally, the self refers to the instance itself. 实际上, instance.instance_method()会在内部变成TheClass.instance_method(instance)self引用实例本身。 so the first and the second versions are equals to each other. 因此第一个和第二个版本彼此相等。

a simple example: 一个简单的例子:

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"

In the second print statement, polly is passed as the self argument to the class method. 在第二个print语句中,将polly作为self参数传递给class方法。 This happened implicitly in the first print statement. 这在第一个打印语句中隐式发生。 On the third print, the class method is called, but there is no actual object with data to act on. 在第三张图上,将调用class方法,但没有实际对象可以处理数据。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM