使用自我论证

时间:2011-12-28 15:50:02

标签: python self

我是Python的新手。我不明白如何/为什么使用self参数:

class Person:
    def __init__(self, name):
        self.name = name
    def sayHi(self):
        print 'Hello, my name is', self.name

p = Person('Swaroop')
p.sayHi()

此代码来自Python的Byte。这段代码可以很容易地编写为:

def sayHi(self, name):
            print 'Hello, my name is', name

p = Person('Swaroop')
p.sayHi()

...对吧?将name字段设为self的目的是什么?

5 个答案:

答案 0 :(得分:6)

似乎你过分简化了一件不那么简单的事情。 在面向对象的编程中,Class是一个声明构造,它给出了一个蓝图,说明对象(这个蓝图的一种表现形式)将包含什么(属性)以及它将如何表现(成员)。 这种类的每个表现形式都称为对象,它具有已定义的特定实例。从一个对象通过任何称为成员函数/方法的行为属性,我们需要以某种方式引用该对象的实例并记住其中的各个元素,并与其他非成员实体明确区分。

考虑你的例子

class Person:
    def __init__(self, name):
        self.name = name
    def sayHi(self):
        print 'Hello, my name is', self.name

此人的每个实例(Tom,Dick,Harry)都是独一无二的,并且在每个实例中,为了回顾自身,我们需要一些习惯用法(在Python中自我,这个ptr是C ++或Java中的这个)。

因此,在__init__方法中,当您需要使用name参数在Person的name属性之间划分时,我们可以使用self轻松完成此操作。不仅如此,在任何情况下,我们都可以通过self继续引用此名称。

创建Person p=Person('Swaroop')的实例,然后调用sayHi,与仅调用一个不是对象一部分的函数sayHi形成对比有两个含义

  1. 功能是短暂的,没有状态,没有实例和它的喜欢说这个家伙“嘿先生你曾经说过'你好,我的名字是Swaroop'”。就像每次跑步一样,你必须让一个愚蠢的人知道他的名字会忘记下一刻你会遇见他。这就像盖伊患有 Anterograde_amnesia 一样。另一方面,调用名为Swaroop的Person实例的sayHi将意味着一个物理上存在的Swaroop问候回到他的名字,他有一个持久的记忆,除非他采用新的名字,否则永远不会忘记。
  2. 该功能永远不会记住,但每次通话结束时都会忘记。在您明确或隐含地杀死该人之前,Person对象将记住该名称。
  3. 如果你有C ++的背景,可能想知道为什么我们需要在函数调用中添加那个额外的参数,而在C ++中这个指针永远不会传递。 坦率地说它确实如此。如果您阅读C ++调用约定,无论是X86还是X64,那么this指针将通过寄存器ecx传递给方法,以便为自己提供句柄。这里更明确的是我们故意将句柄传递给方法的当前实例。

答案 1 :(得分:4)

查看新方法sayHiTo

class Person:
    def __init__(self, name):
        self.name = name
    def sayHi(self):
        print 'Hello, my name is', self.name
    def sayHiTo(self, other):
        print 'Hello', other.name, ' my name is', self.name

p1 = Person('Swaroop')
p2 = Person('codeninja')
p1.sayHiTo(p2)
p2.sayHiTo(p1)

答案 2 :(得分:2)

其实没有。你的第二个例子不正确。 'self'关键字是一个特殊的引用,它被传递给类的实例方法。它表示该范围内类的实际实例。当你上课时,它只是一般定义。然后,您创建该类的实例。每个实例都是唯一的,因此方法必须能够在该实例上工作。在制作之前你无法了解它们,所以“自我”会为你传递它们。

例如,如果您创建了person person的两个实例:

p1 = Person("john")
p2 = Person("sam")

每个人的self.name值都不同。当你在每个实例上调用sayHi()时:

p1.sayHi()
> Hello, my name is john
p2. sayHi()
> Hello, my name is sam

您不会将self关键字用于未绑定的函数。也就是说,只是像你的第二个例子所写的一般功能。你必须像这样写它;

def sayHi(name):
        print 'Hello, my name is', name

    p = Person('Swaroop')
    p.sayHi()

> sayHi("john")

但这基本上只是将一个名称字符串传递给Person类并调用其方法。这里的想法是您使用自己的属性创建Person的唯一实例。

答案 3 :(得分:0)

目的是存储对名称的引用,以便您可以在该类的另一种方法中引用它,例如def sayHi (self)

答案 4 :(得分:0)

您无法将类中的函数与函数进行比较。当然你可以传递名字,但使用类的想法是你封装数据。将vars链接到self意味着您可以传递一个对象,并且该对象始终可以访问其“成员变量”。其他一些类可以使用Person的实例,而不需要知道那些人的名字才能说出来。