• 技术文章 >Python技术 >Python基础教程

    python self用法详解

    silencementsilencement2019-07-02 14:20:04原创4087

    对于在类体中定义的实例方法,Python 会自动绑定方法的第一个参数(通常建议将该参数命名为 self),第一个参数总是指向调用该方法的对象。根据第一个参数出现位置的不同,第一个参数所绑定的对象略有区别:

    在构造方法中引用该构造方法正在初始化的对象。

    在普通实例方法中引用调用该方法的对象。

    由于实例方法(包括构造方法)的第一个 self 参数会自动绑定,因此程序在调用普通实例方法、构造方法时不需要为第一个参数传值。

    self 参数(自动绑定的第一个参数)作用就是引用当前方法的调用者,比如前面介绍的在构造方法中通过 self 为该对象增加实例变量。也可以在一个实例方法中访问该类的另一个实例方法或变量。假设定义了一个 Dog 类,这个 Dog 对象的 run() 方法需要调用它的 jump() 方法,此时就可通过 self 参数作为 jump() 方法的调用者。

    方法的第一个参数所代表的对象是不确定的,但它的类型是确定的,即它所代表的只能是当前类的实例;只有当这个方法被调用时,它所代表的对象才被确定下来谁在调用这个方法,方法的第一个参数就代表谁。

    例如定义如下 Dog 类:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    class Dog:

        # 定义一个jump()方法

        def jump(self):

            print("正在执行jump方法")

        # 定义一个run()方法,run()方法需要借助jump()方法

        def run(self):

            # 使用self参数引用调用run()方法的对象

            self.jump()

            print("正在执行run方法")

    上面代码的 run() 方法中的 self 代表该方法的调用者:谁在调用 run() 方法,那么 self 就代表谁。因此该方法表示:当一个 Dog 对象调用 run() 方法时,run() 方法需要依赖它自己的 jump() 方法。

    当 Python 对象的一个方法调用另一个方法时,不可以省略 self。也就是说,将上面的 run()方法改为如下形式是不正确的:

    1

    2

    3

    4

    5

    # 定义一个run()方法,run()方法需要借助jump()方法

    def run():

        #省略self,下面代码会报错

        self.jump()

        print("正在执行run方法")

    此外,在构造方法中,self 参数(第一个参数)代表该构造方法正在初始化的对象。例如如下代码:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    class InConstructor :

        def __init__(self) :

            # 在构造方法里定义一个foo变量(局部变量)

            foo = 0

            # 使用self代表该构造方法正在初始化的对象

            # 下面的代码将会把该构造方法正在初始化的对象的foo实例变量设为6

            self.foo = 6

    # 所有使用InConstructor创建的对象的foo实例变量将被设为6

    print(InConstructor().foo) # 输出6

    在 InConstructor 的构造方法中,self 参数总是引用该构造方法正在初始化的对象。程序中将正在执行初始化的 InConstructor 对象的 foo 实例变量设为 6,这意味着该构造方法返回的所有对象的 foo 实例变量都等于 6。

    需要说明的是,自动绑定的 self 参数并不依赖具体的调用方式,不管是以方法调用还是以函数调用的方式执行它,self 参数一样可以自动绑定。例如如下程序:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    class User:

        def test(self):

            print('self参数: ', self)

            

    u = User()

    # 以方法形式调用test()方法

    u.test() # <__main__.User object at 0x00000000021F8240>

    # 将User对象的test方法赋值给foo变量

    foo = u.test

    # 通过foo变量(函数形式)调用test()方法。

    foo() # <__main__.User object at 0x00000000021F8240>

    上面程序中第 5 行代码以方法形式调用 User 对象的 test() 方法,此时方法调用者当然会自动绑定到方法的第一个参数(self 参数);程序中第 11 行代码以函数形式调用 User 对象的 test() 方法,看上去此时没有调用者了,但程序依然会把实际调用者绑定到方法的第一个参数,因此输出结果完全相同。

    当 self 参数作为对象的默认引用时,程序可以像访问普通变量一样来访问这个 self 参数,甚至可以把 self 参数当成实例方法的返回值。看下面程序:

    1

    2

    3

    4

    5

    6

    7

    8

    9

    10

    11

    12

    class ReturnSelf :

        def grow(self):

            if hasattr(self, 'age'):

                self.age += 1

            else:

                self.age = 1

            # return self返回调用该方法的对象

            return self

    rs = ReturnSelf()

    # 可以连续调用同一个方法

    rs.grow().grow().grow()

    print("rs的age属性值是:", rs.age)

    从上面程序中可以看出,如果在某个方法中把 self 参数作为返回值,则可以多次连续调用同一个方法,从而使得代码更加简洁。但是这种把 self 参数作为返回值的方法可能会造成实际意义的模糊,例如上面的 grow 方法用于表示对象的生长,即 age 属性的值加 1,实际上不应该有返回值。

    专题推荐:self用法详解
    上一篇:Python内置函数一览表 下一篇:Python之math模块常用方法汇总

    相关文章推荐

    • Python三目运算符(三元运算符)用法详解• Python类调用实例方法• Python查看模块(变量、函数、类)方法

    全部评论我要评论

    © 2021 Python学习网 苏ICP备2021003149号-1

  • 取消发布评论
  • 

    Python学习网