python是面向对象的,所以自然离不开类和对象,我们今天就来着重说一下python面向对象编程。(面向对象的基础知识不再补充)
类的定义
首先是类的定义:
class name:
pass
我们能看一下格式,首先是一个普通的class,然后是我们类的名字,冒号后则是类的具体内容。而这里的pass并不是我随便写的,而是有含义的。当我们创建了一个空的类或方法,并且一时半会不想设计它的内容,我们就需要为其加上一个pass来告诉编译器,这是一个空的类或函数。
self
我们在类中有时候需要调用自身,比如一个对象需要调用自身的某个变量,但是因为被局部变量屏蔽,不得不直接调用,那就需要用self:
class cgg:
def __init__(self,arg):
self.arg=arg
对象
既然有了类,那就不能少了对象,要不然要类干啥?
那么我们通过之前的学习知道了,python中创建变量时并没有明确的类型声明,那么我们不禁感到迷惑,我们应该怎么去定义一个类的对象呢?
在python中我们需要这样操作:
jim=cgg("cgg")
访问对象的属性
有了对象,我们就可以调用它的属性了:
a=cgg("cgg")
print(a.arg)
对象的内置类属性
我们的类除了我们自己写的一些属性,还有一些内置的属性,也就是本身就有的:
属性 | 描述 |
---|---|
__dict__ | 类的属性(包含一个字典,由类的数据属性组成) |
__doc__ | 类的文档字符串 |
__name__ | 类名 |
__module__ | 类定义所在的模块(类的全名是’main.className’,如果类位于一个导入模块mymod中,那么className.module 等于 mymod) |
__bases__ | 类的所有父类构成元素(包含了一个由所有父类组成的元组) |
简单说一下类的文档字符串,所谓文档字符串,就是在类的开头类似说明用的一行字符串,比如:
class cgg:
"这是cgg的类"
def __init__(self,arg):
self.arg=arg
这时我们输出文档字符串:
print(a.__doc__)
就得到:这是cgg的类
对象回收
python会为每个对象设置一个引用计数器,也就是说每增加一个引用,计数器就加一,当计数器变为0时,这个对象就会在合适的时间被回收。
这也就会提到类的析构函数:
class cgg:
"这是cgg的类"
def __init__(self,arg):
self.arg=arg
def __del__(self):
print("我被回收啦!")
我们尝试回收对象:
a=cgg("cgg")
del a
然后就会输出:我被回收啦!
继承
python依然保持了继承的特性。
那么怎么声明一个类的父类是谁呢?
如下:
class cgg:
pass
class son(cgg):
pass
这样,我的儿子就诞生了(没错,它没有妈妈,就像我现在单身一样)
由于继承关系,子类的对象是可以使用父类的函数的。
当然了,父类的变量也是继承的。
同时,python支持多继承:
class cgg:
"这是cgg的类"
def __init__(self,arg):
self.arg=arg
def __del__(self):
print("我被回收啦!")
class Misaka:
"这是cgg的老婆"
def __init__(self):
pass
class son(cgg,Misaka):
pass
看现在它就变成了我和Misaka的孩子了。
python 也是支持方法的重写的,可以覆盖父类方法。
基础的重载方法
序号 | 方法, 描述 & 简单的调用 |
---|---|
__init__ ( self [,args…] ) | 构造函数;简单的调用方法: obj = className(args) |
__del__( self ) | 析构方法, 删除一个对象;简单的调用方法 : del obj |
__repr__( self ) | 转化为供解释器读取的形式;简单的调用方法 : repr(obj) |
__str__( self ) | 用于将值转化为适于人阅读的形式;简单的调用方法 : str(obj) |
__cmp__ ( self, x ) | 对象比较;简单的调用方法 : cmp(obj, x) |
运算符的重载
我们也可以对一些运算符进行重载:
class vector:
def __init__(self,x,y):
self.x=x
self.y=y
def __add__(self,a):
return vector(self.x+a.x,self.y+a.y)
def printv(self):
print("(%s,%s)"%(self.x,self.y))
a=vector(1,2)
b=vector(2,3)
c=a+b
c.printv()
这里我们就实现了向量的相加
类属性和方法
我们知道在很多编程语言中有public、private、protected,那么python里能不能定义私有变量呢?答案是肯定的。
我们可以在一个变量的名字前加上双下划线来定义为私有变量:
class cgg:
def __init__(self,ac):
self.__ac=ac
如果我们对这个变量进行调用会产生异常:
a=cgg(12)
print(a.__ac)
但是我们采用如下方法来调用:
a=cgg(12)
print(a._cgg__ac)
也就是对象名._类名__属性名
同样我们可以定义私有的方法,只要在方法的前面加上双下划线就好:
class cgg:
def __init__(self,ac):
self.__ac=ac
def __eat(self):
print("吃饭了")
def begin(self):
print("开始了")
self.__eat()
我们如果在外部调用,会报错。
但是我们可以在内部调用,如上述begin方法。
下划线的说明
示例 | 说明 |
---|---|
__foo__ | 定义的是特殊方法,一般是系统定义名字 ,类似 init() 之类的。 |
_foo: | 以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问,不能用于 from module import * |
__foo | 双下划线的表示的是私有类型(private)的变量, 只能是允许这个类本身进行访问了。 |