类的定义
假如要定义一个类 Point,表示二维的坐标点:
# point.pyclass Point: def __init__(self, x=0, y=0): self.x, self.y = x, y
最最基本的就是 __init__ 方法,相当于 C++ / Java 的构造函数。带双下划线 __ 的方法都是特殊方法,除了 __init__ 还有很多,后面会有介绍。
参数 self 相当于 C++ 的 this,表示当前实例,所有方法都有这个参数,但是调用时并不需要指定。
>>> from point import *>>> p = Point(10, 10) # __init__ 被调用>>> type(p)<class 'point.Point'>>>> p.x, p.y(10, 10)
几乎所有的特殊方法(包括 __init__)都是隐式调用的(不直接调用)。
对一切皆对象的 Python 来说,类自己当然也是对象:
>>> type(Point)<class 'type'>>>> dir(Point)['__class__', '__delattr__', '__dict__', ..., '__init__', ...]>>> Point.__class__<class 'type'>
Point 是 type 的一个实例,这和 p 是 Point 的一个实例是一回事。
现添加方法 set:
class Point: ... def set(self, x, y): self.x, self.y = x, y
>>> p = Point(10, 10)>>> p.set(0, 0)>>> p.x, p.y(0, 0)
p.set(...) 其实只是一个语法糖,你也可以写成 Point.set(p, ...),这样就能明显看出 p 就是 self 参数了:
>>> Point.set(p, 0, 0)>>> p.x, p.y(0, 0)
值得注意的是,self 并不是关键字,甚至可以用其它名字替代,比如 this:
class Point: ... def set(this, x, y): this.x, this.y = x, y
与 C++ 不同的是,“成员变量”必须要加 self. 前缀,否则就变成类的属性(相当于 C++ 静态成员),而不是对象的属性了。
访问控制
Python 没有 public / protected / private 这样的访问控制,如果你非要表示“私有”,习惯是加双下划线前缀。
class Point: def __init__(self, x=0, y=0): self.__x, self.__y = x, y def set(self, x, y): self.__x, self.__y = x, y def __f(self): pass
__x、__y 和 __f 就相当于私有了:
>>> p = Point(10, 10)>>> p.__x...AttributeError: 'Point' object has no attribute '__x'>>> p.__f()...AttributeError: 'Point' object has no attribute '__f'
_repr_
尝试打印 Point 实例:
>>> p = Point(10, 10)>>> p<point.Point object at 0x000000000272AA20>
通常,这并不是我们想要的输出,我们想要的是:
>>> pPoint(10, 10)
添加特殊方法 __repr__ 即可实现:
class Point: def __repr__(self): return 'Point({}, {})'.format(self.__x, self.__y)
新闻热点
疑难解答