写一篇Python类的入门文章,在高级编程语言中,明白类的概念和懂得如何运用是必不可少的。文章有点长,3000多字。
Python是面向对象的高级编程语言,在Python里面“一切都是对象”:数字、字符串、元组、列表、字典、集合等内置数据类型,以及函数、方法、类、模块都是对象。
class
实现的,下面是最简单的类的定义的样子:class ClassName:
语句1
...
语句n
语句1
可能是内部变量(数据)的定义和赋值语句,也可能是内部方法(函数)的定义语句。类内部的函数定义通常具有一种特别形式的参数列表,这是方法调用的约定规范里面指明的。这个特别形式就是第一个参数必须是self
,后面将详细介绍。ClassName
)。ClassName
)支持两种操作:属性引用和实例化。obj.name
。类对象被创建时存在于类命名空间内的所有名称都是有效的属性名称。下面是一个包含数据和方法的简单的类定义:class YuanRenXue:
'''A demo of class'''
name = '猿人学'
def say_hi(self):
print('Hello world!')
YuanRenXue.name
YuanRenXue.say_hi
,Yuanrenxue.name
的值。__doc__
也是一个有效的属性,对他的引用会返回所属类的文档字符串:'A demo of class'
。yrx = YuanRenXue()
yrx
。__init__()
的特殊方法。它是类实例化的初始化方法,跟C++语言中 的构造函数类似。def __init__(self):
self.data = None
__init__()
方法后,类的实例化操作会自动调用该方法。__init__()
方法也可以有额外(除self之外)的参数以实现更灵活的初始化操作。类对象实例化时(“调用”类对象)传递的参数会被传递给__init__()
方法。例如:In [27]: class Point:
...: def __init__(self, x, y):
...: self.x = x
...: self.y = y
...:
In [28]: p = Point(7, 8)
In [29]: p.x, p.y
Out[29]: (7, 8)
p
是声明创建的Point
的实例,则以下代码会打印数值8
:p.times = 1
while p.times < 5:
p.times = p.times * 2
print(p.times)
del p.times
p.times
并没有在类定义时声明(数据属性不需要声明),但在任何时候,我们可以给实例赋值一个新的数据属性(这里是p.times
),并可以随时删除实例的数据属性(del p.times
)。append(), insert(), sort()
等方法。yrx.say_hi
是有效的方法引用,因为YuanRenXue.say_hi
是一个函数;而yrx.name
不是方法,因为YuanRenXue.name
不是一个函数。这里要注意,yrx.say_hi
与YuanRenXue.say_hi
并不是一回事,它是一个方法对象,不是函数对象,通俗讲,前者是实例的方法,后者是类的函数。yrx.say_hi()
Hello World
。但是,调用一个方法也可以换另外一种形式,把它赋值给一个变量后再调用。例如:yrx_say = yrx.say_hi
yrx_say()
yrx.say_hi()
时并没有带参数,但say_hi()
函数定义时指定了一个参数。实际上,方法的特殊之处就是实例对象会作为函数的第一个参数(self)被传入。调用yrx.say_hi()
其实就相当于YuanRenXue.say_hi(yrx)
。In [33]: class Tiger:
...: kind = 'feline'
...: def __init__(self, name)
File '<ipython-input-33-16aa1a5937d1>', line 3
def __init__(self, name)
^
SyntaxError: invalid syntax
In [34]: class Tiger:
...: kind = 'feline'
...: def __init__(self, name):
...: self.name = name
...:
In [35]: a = Tiger('Kiro')
In [36]: b = Tiger('Zim')
In [37]: a.kind
Out[37]: 'feline'
In [38]: b.kind
Out[38]: 'feline'
In [39]: a.name
Out[39]: 'Kiro'
In [40]: b.name
Out[40]: 'Zim'
In [42]: class Tiger:
...: places = []
...: def __init__(self, name):
...: self.name = name
...: def go_place(self, place):
...: self.places.append(place)
...:
In [43]: a = Tiger('Kiro')
In [44]: b = Tiger('Zim')
In [45]: a.go_place('北京')
In [46]: b.go_place('上海')
In [47]: a.places
Out[47]: ['北京', '上海']
places
定义为类变量,它就记录了所有老虎(Kiro和Zim,以及后面实例化出来个各个老虎)去过的地方,所以,尽管a
只去过北京,但是当我们通过a
查看places
,也看到了上海。这就是可变对象作为类变量时的特性。如果我们就是想记录所有老虎实例对象去过的地方,这样的用法就是恰到好处。places
定义为实例变量,也就是在__init__()
中进行初始化赋值。self
,代表实例对象。但这只是大家普通认同的一个约定。你可以用任何单词来替代它,但是你的代码让气体程序员读起来就很费劲,也会对VS Code这样的编辑器造成困惑。联系客服