05.27 第六章 类-面向对象

Python支持面向对象,可以自己构建数据结构。

Python支持的OOP风格:

  • 封装:将基本类结构的细节隐藏起来,通过接口实现对实例变量的所有必须访问。
  • 继承:允许基于类的特点创建另一个类。实现代码共享。
  • 多态:指使用运算符或者方法时,根据调用他们的对象执行不同
  • 的操作过程。

类&对象

类是一种类型,创建新类的同时也创建了一个新的类型。

类是建立新对象的模板,对象是通过类创建的。

Python支持面向对象,通过以下方式实现:

class ClassName(BaseClasses): # class 关键字告诉Python定义一个类对象,支持多继承用,分割

"""class doc""" # 通过 ClassName.__doc__ 可以查看

block

BaseClasses是基类,所有类的基类都应该是object。

对象是类的实例,类是抽象的,对象代表具体事物。通过以下方式创建一个对象:

Obj = ClassName([params])

type(ClassName) #<type>

type(Obj) #<type> Obj表示ClassName的对象/<type>

类和实例都有命名空间。

说明:

1、类定义

Python2.x class ClassName(object):

Python3 class ClassName():

属性&方法

  • 属性:

分为类和对象的两种属性。

针对对象的属性,可以使用 object.__dict__ 打印当前对象拥有的属性

类中的每个属性必须有初始值,哪怕这个值是0或者空字符串一般在__init__完成此操作。

Python判断某个类是否存在某个属性的方式:

  • hasattr(class, "attr_name")
  • 静态指定属性

class ClassName():

class_var=0 # class_var 属于类的属性,类似于c++的static,通过 ClassName.class_var 在类内或者类外来访问

def __init__(self): #self 表示调用当前方法的类对象

self.obj_var #obj_var 属于对象的属性

通过 . 来访问属性。还可以通过内置函数操作属性,其中name为属性的str形式,如delattr(obj, "age"):

  1. getattr(obj, name[, default]) : 访问对象的属性。
  2. hasattr(obj,name) : 检查是否存在一个属性。
  3. setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
  4. delattr(obj, name) : 删除属性
  • 动态创建属性

在实例创建之后可以动态的给实例的命名空间增加属性。

new_object = ClassName()

new_object.new_value = 10 # 将new_value 添加到 new_object的命名空间中,但仅存在于

new_object

类也可在定义之后动态添加属性到自己的命名空间,会对已经创建以及即将创建的所有对象生效。

  • 方法,类实例的接口(Python可对数据执行的操作):

类中的函数称为方法。通过def定义第一个参数为 self。类内部方法调用通过self. 调用,不需要传递 self作为第一个参数。

def func1(self):

pass

def func2(self):

self.func1()

self表示类对象“本身”,每个方法的第一个参数必须是self。Python自动将方法的第一个参数映射到调用该方法的对象上。

print self #<__main__.classname instance="" at=""/>

print self.__class__ #__main__.ClassName

Python内置了一些类的属性和方法。

属性:访问方式 ClassName.__xxx__

  1. __dict__ : 类的命名空间(包含一个字典,由类的数据属性组成)
  2. __doc__ :类的文档字符串,也可以使用 obj.__doc__访问
  3. __name__: 类名
  4. __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__ 等于 mymod)
  5. __bases__ : 类的所有父类构成元素(包含了一个由所有父类组成的元组)

基础方法,Python内置方法

  1. __init__(self):构造函数,创建对象时调用,obj = className(args),过程:当调用className(args)时,首先创建默认实例,然后查找__init__(self, params)方法,如果存在则将默认实例映射到 self,将args传递给params。如果不存在__init__(self)则将默认实例返回。

通过该方法,将属性添加到类的任何实例中。

  1. __del__(self):析构函数,使用 del 删除变量与对象的关联时会被调用,del obj
  2. __repr__(self):转化为供解释器读取的形式,repr(obj)
  3. __str__( self ):用于将值转化为可阅读的形式,str(obj)
  4. __cmp__ ( self, x ):对象比较,cmp(obj, x)

类似于c++的个访问权限的属性和方法,Python中所有的方法和属性(实例变量)都是公共的:

1、private:__attr、__func

以双下划线开始,访问权限为私有的,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.

上述Python通过改变名称的方式实现。但不是绝对的,可以通过dir查看更换的名称为_className__attrName 。可以通过修改之后的名称访问 instance._className__attrName。

2、protected:_attr、_func

以单下划线开头的表示的是 protected 类型的变量,即保护类型只能允许其本身与子类进行访问。

3、public:

以字母开头的属性和方法

内置方法

1、__init__ 构造函数

2、__call__ 使用方式为 object()

垃圾回收

Python 使用引用计数实现对象跟踪与垃圾回收。内部记录着所有使用中的对象各有多少引用。当对象的引用计数变为0 时,会被垃圾回收。但是回收不是"立即"的,由解释器在适当的时机,将垃圾对象占用的内存空间回收。

继承

Python 支持多继承,通过继承列表实现。所有类的祖先类是 object,自己定义的类需要继承自object,Python采用object对象来表示类层次结构的顶层对象。所有内置对象(list、tuple等)的父类都是object>

class ClassName(BaseClass, BaseClass2, ...):

pass

1、子类的初始化需要显示调用父类的初始化方法。

2、现在当前类查找方法,然后再去父类查找。

3、子类可以重写父类的同名方法,这个过程叫方法的覆盖(override),也称为方法的重写。

说明:子类调用父类的原理见附录。

方法重载

Python支持运算符重载,需要实现特定的内置方法。并且提供了可重载的特殊运算符集合。

Python基于正在使用的对象类型来区分应用的运算符和方法。

1、==/!=,__eq__

属性函数property()和@property

  • property()

函数原型:property(fget=None,fset=None,fdel=None,doc=None),用于创建和返回一个property对象。定义时在类内部创建 property 对象,将设置与获取方法关联到 property。可以实现 方法类属性的调用方式。

pro_object = property(getxxx,setxxx,fdel=None,doc=None)

其中 pro_object 是一个porperty对象,<type>。Property对象有三个方法,getter(), setter()和delete(),用来在对象创建后设置fget,fset和fdel。/<type>

def set_name(self, name):

pass

def get_name(self):

pass

name = property(get_name, set_name)

obj.set_name 等价 obj.name = 'new_name' ,实际调用 obj.set_name('new_name')

obj.get_name等价 print obj.get_name

说明:print type(Class.name ) # <type>

  • @property (Python装饰器实现方式)

@property广泛应用在类的定义中,负责把一个方法变成属性调用,即调用函数方式跟调用属性一样。同时@property又创建了另一个装饰器@xx.setter,@property通过getter和setter方法来实现。可以看出@property与property功能一样。

@property

def xxx(self): # getter

retrun self.__xxx

@xxx.setter

def xxx(self, yyy): # setter

self.__xxx = yyy

说明:print type(Class.xxx) # <type>


分享到:


相關文章: