在python中,面向对象编程主要有两个主题,就是类和类实例。

1、类

新式类——

class ClassName(bases):'ClassName class doc string'class_suite

经典类——

class ClassName:'ClassName class doc string'class_suite

关键字是class,紧接着是一个类名,随后是定义类的类体代码。新式类和经典类声明的最大不同在于,所有新式类必须继承至少一个父类,参数bases可以是一个或多个用于继承的父类,即单继承或多重继承,而经典类可以不指定父类。object类是所有类的父类。类通常在一个模块的顶层进行定义。

方法——

class ClassName(bases):'ClassName class doc string'def function(self[, args]):pass

定义方法就是在类定义中使用关键字def,这个方法只能被类实例所调用。方法的第一个参数是self关键字,类似于C++的this关键字,self代表实例对象本身,通过类实例调用方法时解释器会自动传入self参数,而不需要我们自己传递self进来。python不支持C++那样的纯虚函数或者抽象方法,作为替代方法,可以简单地在父类方法中引发NotImplementedError异常来获得类似的效果。

静态方法与类方法——

staticmethod()classmethod()是内建的静态方法、类方法装饰器,两者都不需要self参数,后者需要类作为第一个参数,也是由解释器自动传入的。

__init__()方法——

class ChildClass(ParentClass):' ChildClass class doc string'def __init__(self[, args]):ParentClass.__init__(self[, args])pass

__init__()方法类似于C++的构造器,实例化时会首先调用这个函数,作一些初始化工作,子类可能会自动调用父类的这个方法,子类重写了这个方法后,父类的就不会调用了,需要我们在子类中显式地掉用父类的方法,而且要传入self,这是因为我们不是在父类的实例中调用方法,而是在一个子类实例中调用的,这个方法是未绑定的。返回非None的任何其它对象都会导致TpyeError异常。

__new__()方法——

__new__()方法其实更像一个构造器,因为它必须返回一个合法的实例。

__del__()方法——

__del__()方法像个析构器,然而由于python具有靠引用计数的垃圾对象回收机制,这个函数要直到该实例对象所有的引用都被清除掉后才会执行。del减少的是引用计数,不一定会调用这个函数。如果继承自父类,不要忘记首先调用父类的这个函数。

特殊方法——

上面列举了三个特殊方法,其实python还提供了许多其它的特殊方法,以双下划线开始及结尾。这些特殊方法是python中用来扩充类的强有力的方式,可以模拟标准类型,或者重载操作符,如同C++中的操作符重载一样,这些内容后面会有介绍。

类属性——

class C(object):'C class doc string'foo = 100

类属性是与类对象绑定的,不依赖于任何类实例,类似于C++的static关键字。查看类属性可通过内建函数dir()或者访问类的字典属性__dict__,后者等同于内建函数vars()接收类对象作为参数的效果。类属性访问可通过类名或者类实例完成,但类属性的修改只能通过类名进行(如果从实例中访问类属性,恰好类属性是个字典,这时类属性是可以通过实例来修改的)。所以,修改类属性,需要使用类名而不是实例。

特殊类属性——

对任何类C,都有如下特殊类属性

C.__name__

C.__doc__

C.__bases__

C.__dict__

C.__module__

C.__class__

2、实例

实例化——

myObj = Classname()

实例化像调用函数那样,通过一对圆括号来完成。

实例属性——

myObj.name = ‘Blithe’
myObj.age = ‘20’

实例属性不同于类属性,实例属性是这个实例的而不属于类,实例属性能够在“运行时”创建,当一个实例被释放后,它的属性同时也被清除了。构造器是最早可以设置实例属性的地方,因为它是实例创建后第一个被调用的地方。查看实例属性可以像查看类属性一样,使用同样的方法。

特殊实例属性——

对于任意对象I,都仅有如下两个特殊实例属性

I.__class__

I.__dict__

3、类扩展

类扩展有两种方式,一种是类组合,即类属性的类型为某个类对象,另一种是类继承。在上面的介绍中,如果子类重写了父类的某个方法,在子类中调用父类的这个方法时,要通过父类名调用,写入父类名非最佳选择,一个好用的方法是使用super(),如下:

class Parent(object):def foo(self):pass
class Child(Parent):def foo(self):super(Child, self).foo()pass

python2.2以后的版本中,类型和类统一了起来,这样的话,我们就能从标准类型中派生子类,常见用法是重写基类的方法。

多重继承时,经典类和新式类的方法搜索顺序MRO不同,前者使用深度优先算法,而后者继承自object,新的菱形类继承结构出现了,需使用广度优先算法。

4、有用的内建函数

issubclass(sub,sup):判断sub类是否是sup类的子类或者子孙类,sup可以是sub自身,还可以是许多类组成的元组。

isinstance(obj1,obj2):判断obj1是否是obj2的实例,obj2可以是元组。

hasattr(obj,'attr'):判断obj是否包含attr属性。

getattr(obj,'attr'[,value]):获取obj中的attr属性,没有这个属性时会触发AttributeError异常,可设置属性的默认值value。

setattr(obj,'attr',value):设置obj中的attr属性。

delattr(obj,'attr'):删除obj中的attr属性。

dir([obj]):显示obj的属性,参数可以是类、实例、模块,不带参数时显示调用者的局部变量。

super(type[,obj]):前面介绍过,这个函数的目的就是帮助找出父类。对于每个定义的类,都有一个名为__mro__的属性,它是一个元组,按照它们被搜索时所顺序,列出了备搜索的类。

vars([obj]):与内建函数dir()相似,只是这个函数的obj必须有一个__dict__属性,否则会触发TypeError异常。

5、定制类

前面提到了特殊方法,我们可以使用特殊方法来定制类,扩展类功能。

下面是一个简单的例子,RoundFloat类用来对一个float数值进行四舍五入,保留两位小数,__init__()中的assert判断构造器输入参数必须是一个float数值,否则会触发异常,异常参数是一个自定义的字符串,__str__()是用来支持print语句的,__repr__()是__str__()的别名,支持真正的字符串对象显示出来。

class RoundFloat(object): def __init__(self, val): assert isinstance(val, float), \ "value must be a float!" self.value = round(val, 2) def __str__(self): return "%.2f" %self.value __repr__ = __str__

6、私有化

默认情况下,属性在python中都是public的。python的类并没有像C++那样的private等关键字用于属性可见性标识,但有其它的方法。私有元素以双下划线开头,直接访问是不允许的,例如类C中的self.__age元素,访问时必须是self._C__age,元素前加单个下划线和类名。双下划线的另一个好处是保护变量不与父类名字空间相冲突。

7、包装

包装,意思是对一个已存在的对象进行包装,增加新的、删除不要的、或者修改其它已存在的功能,它的实例拥有标准类型的核心行为,同时又表现出与原类不同的行为。授权是包装的一个特性,授权的过程,即是所有更新的功能都是由新类的某部分来处理,但已存在的功能就授权给对象的默认属性。

实现授权的关键点就是覆盖__getattr__()方法,在代码中包含一个对getattr()内建函数的调用。特别地,调用getattr()以得到默认对象属性并返回它,以便访问或调用。特殊方法__getattr__()的工作方式是,当搜索一个属性时,任何局部对象首先被找到,如果搜索失败了,则__getattr__()会被调用,然后调用getattr()得到任何一个对象的默认行为。

8、新式类

与经典类相比,新式类统一了类型和类,最重要的特性是能够子类化python数据类型,不过许多内建函数都转化成为了工厂函数,当这些函数被调用时,实际上是对相应的类型进行实例化。

__slots__类属性——

__dict__字典属性可以跟踪所有的实例属性,但会占据大量内存,为内存上的考虑,可以使用__slots__类属性替代字典属性。__slots__可以是一个列表、元组或可迭代对象,也可以是标识实例能拥有的唯一属性的简单字符串,任何试图创建一个其名不在__slots__中的名字的实例属性都将导致AttributeError异常。带__slots__属性的类定义不会存在__dict__。

__getattribute__()特殊方法——

前面提到的__getattr__()特殊方法仅当属性不能在__dict__中找到时才被调用,包装授权中用到了这个函数,__getattribute__()类似前者,不同之处在于当属性被访问时,它就一直可以被调用,而不局限与不能找到的情况。如果类同时定义了这两个方法,除非明确从后者调用或引发AttributeError异常,否则前者不会被调用。

描述符——

描述符是python新式类的关键点之一,它为对象属性提供了强大的API,可以认为描述符是表示对象属性的一个代理。当需要属性时,常规方式是通过句点访问,如果有描述符的话也可以用来访问属性。描述符实际上可以是任何类,这种类至少实现了三个属性操作的特殊方法__get__()、__set__()、__delete__()中的一个。

整个描述符系统的核心是__getattribute__(),它的实现方式很特别,有一定的优先级顺序,从高到低依次是类属性、数据描述符、实例属性、非数据描述符及默认的__getattr__()。

静态方法、类方法、属性,甚至所有的函数都是描述符。属性是一种有用的特殊类型的描述符,property()内建函数原型如下:

property(fget=None, fset=None, fdel=None, doc=None)

下面是property的一个简单用法:

class C(object): def getx(self): return self._x def setx(self, value): self._x = value def delx(self): del self._x x = property(getx, setx, delx, "I'm the 'x' property.")

property还可用作装饰器:

class C(object): @property def x(self): return self._x @x.setter def x(self, value): self._x = value @x.deleter def x(self): del self._x 

元类——

元类用来定义某些类是如何被创建的,拥有创建类的控制权,相关的类属性是__metaclass__,传统类(找不到__metaclass__)的元类为types.ClassType。元类通常传递三个参数到构造器,分别是类名、从基类继承数据的元组和属性字典。

下面是元类应用的一个例子,它只是在用元类创建一个类时,显示时间标签:

#!/usr/bin/env python from time import ctime print '*** Welcome to Metaclasses!'
print '\tMetaclass declaration first.' class MetaC(type): def __init__(cls, name, bases, attrd): super(MetaC, cls).__init__(name, bases, attrd) print '*** Created class %r at: %s' %(name, ctime()) print '\tClass "Foo" declaration next.' class Foo(object): __metaclass__ = MetaC def __init__(self): print '*** Instantiated class %r at: %s' %(self.__class__.__name__, ctime()) print '\tClass "Foo" instantiation next.'
f = Foo()
print '\tDONE'

下面是log输出:

*** Welcome to Metaclasses! Metaclass declaration first. Class "Foo" declaration next.
*** Created class 'Foo' at: Thu Jun  4 10:03:06 2015 Class "Foo" instantiation next.
*** Instantiated class 'Foo' at: Thu Jun  4 10:03:06 2015 DONE 

下面是元类应用的一个稍微复杂的例子,要求新创建的类重写__str__()和__repr__()两个方法,如果没有的话,前者触发异常,后者引起警告。

#!/usr/bin/env python from warnings import warn class ReqStrSugRepr(type): def __init__(cls, name, bases, attrd): print '*** Defined ReqStrSugRepr (meta)class\n' super(ReqStrSugRepr, cls).__init__(name, bases, attrd) if '__str__' not in attrd: aerror = 'Class %r requires overriding of __str__()' %name raise TypeError(aerror) if '__repr__' not in attrd: awarn = 'Class %r suggests overriding of __repr__()\n' %name warn(awarn, stacklevel = 3) print '*** Created %r class\n' %name class Foo(object): __metaclass__ = ReqStrSugRepr def __str__(self): return 'Instance of class:', self.__class__.__name__ def __repr__(self): return self.__class__.__name__ class Bar(object): __metaclass__ = ReqStrSugRepr def __str__(self): return 'Instance of class:', self.__class__,__name__ class FooBar(object): __metaclass__ = ReqStrSugRepr

下面是log输出:

*** Defined ReqStrSugRepr (meta)class *** Created 'Foo' class *** Defined ReqStrSugRepr (meta)class sys:1: UserWarning: Class 'Bar' suggests overriding of __repr__() *** Created 'Bar' class *** Defined ReqStrSugRepr (meta)class Traceback (most recent call last): File "./metaCEx2.py", line 39, in <module> class FooBar(object): File "./metaCEx2.py", line 13, in __init__ raise TypeError(aerror)
TypeError: Class 'FooBar' requires overriding of __str__() 

9、几个模块

UserList:提供一个列表对象的封装类。

UserDict:提供一个字典对象的封装类。

UserString:提供一个字符串对象的封装类,它又包括一个MutableString子类。

types:定义所有python对象的类型在标准python解释器中的名字。

operator:标准操作符的函数接口。

【Python】python面向对象编程相关推荐

  1. python用类名直接调用方法_一文读全 Python 的面向对象编程方法

    背景介绍: Python 支持三种形式的编程,分别是:"命令式"."函数式"和"面向对象式". 很多优秀的开源 Python 项目里都用到了 ...

  2. Python设计模式面向对象编程

    前言 本篇文章是基于极客时间王争的<设计模式之美>做的总结和自己的理解.   说到面向对象编程,作为一个合格的Pythoner,可以说信手拈来.毕竟在Python里"万物都是对象 ...

  3. 零基础入门学习Python(35)面向对象编程

    self是什么? Python的self相当于C++的this指针 由同一个类可以生成无数对象,当一个对象的方法被调用的时候,对象会将自身的引用作为第一个参数传给该方法,Python就知道要操作哪个对 ...

  4. Python 进阶 — 面向对象编程

    目录 文章目录 目录 面向对象思想 面向对象编程 面向对象编程的特性 封装 继承 多态 面向对象编程的优势 Python 的类属性与类方法 Python 类的实例化 Python 的对象属性与对象方法 ...

  5. Python基础-面向对象编程

    本文完全转载自廖雪峰大神的教程: 面向对象编程 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数 ...

  6. python的面向对象编程学生成绩_python的类_面向对象编程

    摘自谬雪峰https://www.liaoxuefeng.com/wiki/1016959663602400/1017496031185408 面向对象编程(定义对象)和面向过程(定义函数)的区别,各 ...

  7. python采用面向对象编程模式吗_在python中,面向对象还有用吗?

    面向对象是一种编程思想,跟语言无关. 任何人但凡稍微看一下面向对象的概念和意义就会知道,目前的工程化的编程是不可能脱离面向对象的.例如编程语言界的扛把子 Java 就是完全的面向对象语言,用 Java ...

  8. python中面向对象编程简称为_Python基础-面向对象编程

    本文完全转载自廖雪峰大神的教程: 面向对象编程--Object Oriented Programming,简称OOP,是一种程序设计思想.OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的 ...

  9. python采用面向对象编程模式吗_如何理解 Python 中的面向对象编程?

    现如今面向对象编程的使用非常广泛,本文我们就来探讨一下Python中的面向对象编程. 作者 | Radek Fabisiak 译者 | 弯月,责编 | 郭芮 以下为译文: Python支持多种类型的编 ...

  10. 2013.01.16 Python的面向对象编程

    看起来貌似我的接收能力貌似很差劲,看了一个多星期才看到Python简明教程的第十三章(面向对象编程).回想一下前面看的内容,大部分都已经忘了,随便写几句代码还得回过头去翻教程,怎么办?是好还是坏?求指 ...

最新文章

  1. 数字政通图像处理面试_SLAM面试问题大全
  2. 函数名/函数地址/函数指针
  3. 安卓案例:联选系部与专业
  4. 60-10-040-命令-数据的路径间迁移kafka-reassign-partitions.sh
  5. SpringMVC+Spring Data JPA +Bootstrap 分页实现和模糊查询分页
  6. 人脸识别 java_利用Java调用OpenCV进行人脸识别
  7. RK3399触摸不准,修改drivers中gt9xx.h的cfg
  8. 一键抓取网页的所有图片
  9. 臀部肌群锻炼方法大全
  10. P4167 [Violet]樱花
  11. 熟练运用计算机软件英语,计算机软件英语论文
  12. 汉威危化品安全风险监测预警平台 助力企业摆脱新旧领域风险
  13. [翻译]2020年综述:基于深度学习的视频超分辨率
  14. I2C总线的SDA和SCL
  15. 阿里云Centos7.x安装中文支持
  16. iOS view生命周期
  17. 使用QT SDK 1.1 Qt Creator 2.0.9创建symbian sisx安装包
  18. 记录javacv-platform截取rtsp图片和拍摄MP4
  19. 卷完职场卷AI,测试真的会被ChatGPT代替吗?
  20. JS使用sort进行升序和降序排序

热门文章

  1. 机器学习16:半监督学习semi-supervised
  2. 建立图书馆目录索引的树型目录,并显示书籍的相关信息
  3. DIv2 770 B. Fortune Telling
  4. Lustre参数调整
  5. 常见水果对肠道菌群、肠道蠕动和便秘的影响
  6. 【精彩推荐】RT-Thread操作系统μC/OS-III兼容层
  7. NetApp RLM 登录
  8. 立式离心泵的工作原理与维护
  9. DOM——页面文档对象模型 (2)
  10. das 2.0开发记录