你现在的位置: 首页 > 深入 Python > 对象和面向对象 > 定义类 | << >> | ||||
深入 Python从 Python 新手到专家 |
Python 是完全面向对象的:您可以定义自己的类,从您自己的类或内置类继承,并实例化您定义的类。
在 Python 中定义一个类很简单。与函数一样,没有单独的接口定义。只需定义类并开始编码。一个 Python 类以保留字 class 开始,后面跟着类名。从技术上讲,这就是必需的全部内容,因为类不需要从任何其他类继承。
![]() |
|
Python 中的 pass 语句类似于 Java 或 C 中的一组空括号 ({})。 |
当然,实际上,大多数类都将从其他类继承,并且它们将定义自己的类方法和属性。但是正如您刚刚看到的,除了名称之外,类没有绝对必须拥有的东西。特别是,C++ 程序员可能会发现 Python 类没有显式的构造函数和析构函数很奇怪。Python 类确实有类似于构造函数的东西:__init__ 方法。
from UserDict import UserDict class FileInfo(UserDict):
![]() |
在 Python 中,类的祖先简单地列在类名后面的括号中。所以 FileInfo 类是从 UserDict 类继承的(它是从 UserDict 模块导入的)。UserDict 是一个像字典一样工作的类,允许您基本上子类化字典数据类型并添加您自己的行为。(还有类似的类 UserList 和 UserString 允许您子类化列表和字符串。)这背后有一些黑魔法,当您在本章后面更深入地探讨 UserDict 类时,您将揭开它的神秘面纱。 |
![]() |
|
在 Python 中,类的祖先简单地列在类名后面的括号中。没有像 Java 中的 extends 这样的特殊关键字。 |
Python 支持多重继承。在类名后面的括号中,您可以列出任意数量的祖先类,用逗号分隔。
此示例显示了使用 __init__ 方法初始化 FileInfo 类。
class FileInfo(UserDict): "store file metadata"def __init__(self, filename=None):
![]()
![]()
![]() |
类也可以(并且应该)像模块和函数一样拥有 文档字符串。 |
![]() |
__init__ 在创建类的实例后立即被调用。将此称为类的构造函数是诱人的,但不正确。之所以诱人,是因为它看起来像一个构造函数(按照惯例,__init__ 是为类定义的第一个方法),行为也像一个构造函数(它是新创建的类实例中执行的第一段代码),甚至听起来也像一个构造函数(“init”当然暗示了构造函数的性质)。不正确,因为在调用 __init__ 时,对象已经被构造出来了,并且您已经拥有对新类实例的有效引用。但是 __init__ 是您在 Python 中最接近构造函数的东西,它起着几乎相同的作用。 |
![]() |
每个类方法(包括 __init__)的第一个参数始终是对当前类实例的引用。按照惯例,此参数始终命名为 self。在 __init__ 方法中,self 指的是新创建的对象;在其他类方法中,它指的是调用其方法的实例。虽然您在定义方法时需要显式指定 self,但在调用方法时不需要指定它;Python 会自动为您添加它。 |
![]() |
__init__ 方法可以接受任意数量的参数,就像函数一样,参数可以用默认值定义,使其对调用者可选。在这种情况下,filename 的默认值为 None,它是 Python 的空值。 |
![]() |
|
按照惯例,任何 Python 类方法的第一个参数(对当前实例的引用)都被称为 self。此参数在 C++ 或 Java 中扮演着保留字 this 的角色,但 self 在 Python 中不是保留字,而只是一个命名约定。尽管如此,请不要将它称为 self 以外的任何东西;这是一个非常强的约定。 |
在定义类方法时,您必须显式列出 self 作为每个方法的第一个参数,包括 __init__。当您从类内部调用祖先类的方法时,您必须包含 self 参数。但是当您从外部调用类方法时,您不需要为 self 参数指定任何内容;您完全跳过它,Python 会自动为您添加实例引用。我知道这乍一看令人困惑;它实际上并不矛盾,但它可能看起来矛盾,因为它依赖于您尚不了解的区别(绑定方法和未绑定方法之间)。
呼。我知道这需要吸收很多东西,但你会掌握它的。所有 Python 类的工作方式都相同,所以一旦你学会了一个,你就学会了所有。如果你忘记了其他一切,请记住这一件事,因为我保证它会让你绊倒
![]() |
|
__init__ 方法是可选的,但当您定义一个方法时,您必须记住显式调用祖先的 __init__ 方法(如果它定义了一个)。更普遍地说:每当后代想要扩展祖先的行为时,后代方法必须在适当的时候用适当的参数显式调用祖先方法。 |
<< 使用 from module import 导入模块 |
| 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
实例化类 >> |