在 Python 中,类(class)是创建对象的模板:属性(数据)与方法(操作数据的函数)定义在同一类型中。按类实例化得到的每个对象拥有各自的实例属性,方法定义通常由该类所有实例共享。__init__ 在创建对象时完成初始化;实例方法的第一个参数 self 表示当前对象。本节说明类的定义、构造过程及类属性与实例属性的区别。

定义类与创建对象

class 块内定义方法。创建对象时传入的参数进入 __init__ 并绑定到 self;通过 对象.方法() 调用实例方法:

class Dog:
    def __init__(self, name):
        self.name = name

    def bark(self):
        print(f"{self.name}: 汪汪!")

d = Dog("旺财")
d.bark()

类与实例

类描述一类事物的数据与行为;对象是按类创建的具体实例。同一类可创建多个对象,各对象的属性值可不同:

class Dog(图纸) 属性:name 方法:bark() 构造:__init__(name) 实例化 实例化 d1 = Dog("旺财") name = 旺财 d2 = Dog("小黑") name = 小黑
类是一张图纸,能照出无数个实例,每个实例有自己的属性(name),方法(bark)共用一份。
d1 = Dog("旺财")
d2 = Dog("小黑")
d1.bark()
d2.bark()

__init__ 构造过程

执行 Dog("旺财") 时,解释器先创建对象,再自动调用 __init__ 并将新对象作为 self 传入。双下划线包裹的方法为特殊方法,由语法触发,一般不必手动调用 d.__init__(...):

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

p = Person("小明", 20)
print(p.name, p.age)

self 的含义

实例方法的第一个参数约定为 self,表示调用该方法的对象。写成 c.increment() 时,不必在括号中传入 self,解释器会自动绑定:

class Counter:
    def __init__(self):
        self.count = 0

    def increment(self):
        self.count += 1
        return self.count

c = Counter()
print(c.increment())
print(c.increment())

类属性与实例属性

类体中与方法同级的赋值为类属性,通常由该类所有实例共享。在 __init__ 中挂到 self 上的为实例属性,各对象各有一份。修改某一实例的实例属性不影响其他实例;修改类属性可能影响仍通过类访问该属性的实例:

class Student:
    school = "第一中学"

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

s1 = Student("Tom")
s2 = Student("Ann")
print(s1.school, s2.school)
print(s1.name, s2.name)

__str__:字符串表示

默认打印对象常显示类型名与地址。定义 __str__ 返回字符串后,print(对象) 与 str(对象) 将使用该字符串:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return f"({self.x}, {self.y})"

p = Point(3, 5)
print(p)
print(str(p))

实例方法示例

方法在类内定义,通过 self 读写当前对象的属性,使数据与操作集中在一处:

Python 类与方法示例运行
class Rectangle:
    def __init__(self, w, h):
        self.w = w
        self.h = h

    def area(self):
        return self.w * self.h

r = Rectangle(4, 5)
print(r.area())

常见错误

  • 实例方法须保留第一个参数以接收实例(通常命名为 self)。
  • d.bark 得到的是绑定方法对象,执行须写 d.bark()。
  • 各实例不同的数据应使用实例属性;仅全体共享的常量适合类属性。

本节说明了 Python 中类与对象、__init__ 及 self 的用法。下一节介绍继承:子类扩展父类及 super()。