摘要:Python 不仅是一种流行的脚本语言,还支持面向对象编程范式。类描述数据并提供操作数据的方法,所有这些都包含在一个对象中。此外,类将具体的实现细节与数据的抽象表示分离开来,从而实现了抽象。
Python 不仅是一种流行的脚本语言,还支持面向对象编程范式。类描述数据并提供操作数据的方法,所有这些都包含在一个对象中。此外,类将具体的实现细节与数据的抽象表示分离开来,从而实现了抽象。
使用类的代码通常更容易阅读、理解和维护。
1: 类的简介类作为一个模板,定义了特定对象的基本特征。下面是一个例子:
class Person(object):"""A simple class.""" # docstringspecies = "Homo Sapiens" # class attributedef __init__(self, name): # special method"""This is the initializer. It's a specialmethod (see below)."""self.name = name # instance attributedef __str__(self): # special method"""This method is run when Python triesto cast the object to a string. Returnthis string when using print, etc."""return self.namedef rename(self, renamed): # regular method"""Reassign and print the name attribute."""self.name = renamedprint("Now my name is {}".format(self.name))看上面的例子有几点需要注意。
类由属性和方法(功能)组成。属性和方法被简单定义为普通变量和函数。正如相应的文档中指出的,__init__ 方法称为初始化器。它相当于其他面向对象语言中的构造函数,是创建一个新对象或类的新实例时首先运行的方法。首先定义适用于整个类的属性,称为类属性。适用于类的特定实例(对象)的属性称为实例属性。它们通常在 __init__ 中定义;这不是必须的,但我们建议这样做(因为在 __init__ 之外定义的属性有可能在定义之前就被访问)。类定义中包含的每个方法都会将相关对象作为第一个参数传递。这个参数使用了 self 这个词(使用 self 实际上是约定俗成的,因为 self 这个词在 Python 中没有固有的含义,但这是 Python 最受尊重的约定之一,您应该始终遵循它)。习惯于用其他语言进行面向对象编程的人可能会对一些事情感到惊讶。首先,Python 没有私有元素的真正概念,因此默认情况下,一切都模仿 C++/Java public 关键字的行为。有关详细信息,请参阅本页的 “私有类成员 ”示例。该类的某些方法具有以下形式: __functionname__(self, other_stuff)。所有这些方法被称为 “魔法方法”,是 Python 类的重要组成部分。例如,Python 中的运算符重载就是用魔法方法实现的。有关详细信息,请参阅相关文档。现在,让我们为 Person 类创建几个实例!
>>> # Instances>>> kelly = Person("Kelly")>>> joseph = Person("Joseph")>>> john_doe = Person("John Doe")目前,我们有三个 Person 对象:kelly、joseph 和 john_doe。
我们可以使用点运算符 。请再次注意类属性和实例属性之间的区别:
>>> # Attributes>>> kelly.species'Homo Sapiens'>>> john_doe.species'Homo Sapiens'>>> joseph.species'Homo Sapiens'>>> kelly.name'Kelly'>>> joseph.name'Joseph'我们可以使用同样的点操作符 .来执行类的方法:
>>> # Methods>>> john_doe.__str__'John Doe'>>> print(john_doe)'John Doe'>>> john_doe.rename("John")'Now my name is John'Python 3 中删除了绑定和非绑定方法的概念。在 Python 3 中,当您在类中声明一个方法时,会使用 def 关键字,从而创建一个函数对象。这是一个常规函数,周围的类作为它的命名空间。在下面的例子中,我们在类 A 中声明方法 f,它就变成了函数 A.f:
>>> class A(object):def f(self, x):return 2 * x>>> A.f#在 Python 3 中,方法被识别为函数,而在 Python 2 中,这种区别被保留了下来。
import inspect>>> inspect.isfunction(A.f)# True>>> inspect.ismethod(A.f)# False在 Python 的两个版本中,只要传递一个类 A 的实例作为第一个参数,就可以直接调用函数/方法 A.f。
A.f(1, 7)# 输出: 14a = AA.f(a, 20)# 输出: 40现在假设 a 是类 A 的一个实例,那么 a.f 是什么呢?直观地说,这应该是类 A 的同一个方法 f,只是它应该以某种方式 “知道 ”它被应用于对象 a - 在 Python 中,这被称为绑定到 a 的方法。
具体细节如下:写 a.f 会调用 a 的神奇的 __getattribute__方法,它首先检查 a 是否有名为 f 的属性(没有),然后检查类 A 是否包含有这样名字的方法(有),并创建一个新的 method 类型的对象 m,它在 m.__func__ 中有对原始 A.f 的引用,在 m.__self__ 中有对对象 a 的引用。当这个对象作为函数调用时,它只需执行以下操作: m(...) => m.__func__(m.__self__,...)。因此,这个对象被称为 绑定方法,因为当调用它时,它知道要提供绑定的对象作为第一个参数。(在 Python 2 和 Python 3 中,这些工作方式是一样的)。
a = Aa.f# >a.f(2)# 4# 注意:每次调用绑定方法对象 a.f 时,都会重新创建该对象:a.f is a.f # False# 为了优化性能,可以将绑定的方法存储在对象的 __dict__ 中,在这种情况下,方法对象将保持固定:a.f = a.fa.f is a.f # True最后,Python 有类方法和静态方法--特殊类型的方法。类方法的工作方式与普通方法相同,只是在对象上调用时,它们绑定的是对象的类而不是对象。因此,m.__self__ = type(a)。当你调用这种绑定方法时,它会传递 a 的类作为第一个参数。静态方法更简单:它们根本不绑定任何东西,只是简单地返回底层函数,而不进行任何转换。
class D(object):multiplier = 2@classmethoddef f(cls, x):return cls.multiplier * x@staticmethoddef g(name):print("Hello, %s" % name)D.f# >D.f(12)# 24D.g# D.g("world")# Hello, world请注意,即使在实例上访问类方法,类方法也与类绑定:
d = Dd.multiplier = 1337(D.multiplier, d.multiplier)# (2, 1337)d.f# >d.f(10)# 20值得注意的是,在最底层,函数、方法、静态方法等实际上是调用 __get__、__set__ 和可选 __del__特殊方法的描述符。有关 classmethods 和 staticmethods 的更多详情:
来源:山岚