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)的变量, 只能是允许这个类本身进行访问了。