Python3学习笔记(7)—— 面向对象编程
来源:互联网 发布:adobe pdf mac版 编辑:程序博客网 时间:2024/05/29 09:25
1 面向对象编程
1.1 类
1.1.1 定义
命名:类名通常由大写字母打头,数据属性使用名词,方法使用谓词(动词加对象)。推荐使用下划线方式。
类是一个type的实例。如果定义一个类C,则type(C) 是type
可以定义一个空的类,仅用作名称空间容器,然后动态绑定实例属性。
Python 不支持纯虚函数,因此必须在子类中定义方法。
类的定义:
class Sample(baseClass):
'class documentation string' #类文档字符串
def __init__(self, val1, val2): #子类最好定义它自己的构造器,否则基类的构造器会被调用
baseClass.__init__(self,val1)#需显式传递self 实例对象给基类构造器,因为这不是在实例中调用方法。
self.Val2=val2
1.1.2 类属性
①类属性仅与其被定义的类相绑定。类属性可通过类或实例来访问。非静态函数的类方法,只能通过实例访问。
class C(object):
foo = 100
def show():pass
def show1(self):pass
@staticmethod
def show2():pass
@classmethod
def show3(cls):pass
类的数据属性,静态数据,相当于加上了static。调用时C.foo
参数为空。类的方法属性,静态方法,调用时C.show(),不能用实例调用。
self变量表示类实例,用于与实例绑定,通过实例来调用。
静态方法修饰符,下边的函数可以通过类名、实例直接访问。
类方法修饰符,下边函数可通过类名、实例直接访问。但有cls默认参数。
②可以使用一个静态成员(如起名为count)来记录实例的个数。
③访问一个类属性的时候,Python 解释器将会搜索字典以得到需要的属性。如果在__dict__中没有找到,将会在基类的字典中进行搜索,采用“深度优先搜索”顺序。
④特殊的类属性:
C.__name__
类C的名字(字符串)
C.__doc__
类C的文档字符串
C.__bases__
类C的所有父类构成的元组
C.__dict__
或内建函数vars(C)
类C的“属性:值”字典,字符串描述。不包含父类属性,
包括__dict__,__doc__,__module__,__weakref__以及自定义的属性;若未定义__init__(),则不会显示。不要修改__dict__的值。
而实例的__dict__仅存储与该实例相关的实例属性,未绑定属性则是空字典。
C.__module__
对类C定义所在的模块名(字符串)
C.__class__
对实例C对应的类(若对一个类求__class__,则得到“type”)的引用
1.2 实例化
1.2.1 __init__()初始化方法
在实例化时被自动调用,参数self把实例对象自动传入__init__()。
__init__()是解释器创建一个实例后,调用的第一个方法,因此严格意义上不是构造器。不应有非None返回值。
1.2.2 __new__()构造器方法
该方法必须返回一个实例,因此更像一个构造器。可以用于根据条件确定是否返回实例。
def __new__(cls, *args, **kwargs) #cls是当前正在实例化的类名, 由Python解释器自动提供
return object.__new__( cls, *args, **kwargs) #可以return父类__new__()出来的实例
用于定制类
class RoundFloat(float):
def __new__(cls, val):
return super(RoundFloat, cls).__new__(cls, round(val, 2))
1.2.3 __del__()解构器方法
解构器是在类C 实例所有的引用都被清除掉后才被调用的,比如当引用计数已减少到0。
class C(P):
def __del__(self): # "destructor" 解构器
P.__del__(self) # 总是调用父类(或直接是object)的__del__方法
1.2.4 实例属性
给一个与类属性同名的实例属性赋值,会隐藏类属性。一旦删除了这个实例属性,类属性又可见。因此不要使用实例属性来修改类属性,而是使用类属性来修改自身。
1.2.5 type()和isinstance()内建函数
type()
判断type(1)==int
生成新类X=type('X', (object,), dict(a=1,b=2,c=2)) #类名;基类;类内变量
# <class'__main__.X'>
import types;type(1)==types.IntType #减少函数使用次数
isinstance()
判断是否为类的实例,与type()的区别是isinstance()会认为子类是一种父类类型,考虑继承关系
isinstance (a,str)
isinstance (a,(str,int,list))#若是元组中一个,则返回True
1.3 继承
①调用子类属性,会覆盖父类的同名属性,包括__init__()特殊方法。若子类定义了__init__(),子类不会自动调用父类的__init__()。可以使用super()内建函数实现。
②在子类中调用父类的同名方法:
class C(P):
def __init__(self):
super(C,self).__init__()
def foo(self):
P.foo(self)
c=C()
super()会找到父类构造器方法。不必给出父类名称。
调用c.foo()
调用父类的未绑定方法,需传入一个实例。
1.4 访问限制
1.4.1 双下划线“__”
①实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问。
②如果在类中有一个__XXX 属性,它将不会被其子类中的__XXX属性覆盖。因为解释器将其改名为_ClassName__XXX。
③以双下划线开头,并且以双下划线结尾的,是特殊变量,特殊变量是可以直接访问的,用户不要定义。
1.4.2 单下划线“_”
①一个下划线开头的实例变量名,外部可以访问,但是按照约定不要随意访问。
②可以防止模块的属性被“fromMODULE import *”加载。
1.5 内建函数
issubclass(sub, sup)
判断是否是子类或子孙类。sup可以是元组,有任意一个是父类,则返回Ture。当sub==sup时,返回True
isinstance(obj1,obj2)
判断obj1是否是obj2的实例。obj2可以是元组
hasattr(obj, attr)
attr是字符串。返回布尔型。判断对象是否有attr属性
getattr(obj, attr [, default])
获取对象的某属性。若无则返回默认返回值default(未定义则返回AttributeError异常)
setattr(obj, attr)
设置或覆盖对象的某个属性
delattr(obj, attr)
从一个对象中删除属性
dir([object])
__dict__是dir()的子集。dir()会找到类对象或实例的全部属性,包括从父类继承的属性。不会显示定义在元中的类属性; 作用在模块上时,则显示模块的__dict__的内容;不带参数时,则显示调用者的局部变量.
vars(obj=None)
返回__dict__.。对象的属性及其值的一个字典;如果没有给出obj,vars()显示局部命名空间字典(locals())
super(type[, obj])
返回此type 的父类。传入type的实例obj,则绑定父类
1.6 包装与授权
包装:对一个已经存在的对象进行功能定制。
授权:包装类的实例可以直接访问被包装对象的属性,通过在包装类中重写__getattr__()方法。访问属性时先在实例属性中查找,然后在类属性中查找,最后通过__getattr__()查找属性,可以写做:
class Wrapper(object):
def __init__(self,obj):
self. _wrappedObj=obj
def __getattr__(self, attr):
return getattr(self._wrappedObj,attr)
wrappedComplex = Wrapper(3.5+4.2j)
wrappedComplex.real
1.7 高级特性
1.7.1 __slots__
动机:__dict__属性跟踪实例的所有属性,即inst.foo 等价于inst.__dict__['foo']。但是字典占用内存大,若类简单而实例多,可定义__slots__替代__dict__,带__slots__属性的类定义不会存在__dict__,以节约内存。
在定义class的时候,定义一个特殊的__slots__类变量,可以限制该class实例能添加的属性。
__slots__是一个序列对象(列表、元组、可迭代对象)。
__slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的。
class C(object):
__slots__= ('attr1', 'attr2')
1.7.2 @property
property是getter setter deleter三者的集合。用于实现属性的get和set方法。
class C(object):
@property
defname(self):
return self._name
@name.setter
defname(self,value):
ifnot isinstance(value, str):
raise TypeError('Expected a string')
self._name = value
@name.deleter
defname(self):
raiseAttributeError("Can't delete attribute")
1.7.3 描述符
描述符是创建托管属性的方法。描述符具有诸多用途:保护属性不受修改、属性类型检查和自动更新某个依赖属性的值等,是实现了__get__(),__set__()或__delete__()特殊方法的类,该类的实例对象通常是另一个类的类属性。
只实现__get__方法的对象是非数据描述符,只能被读取。而同时实现__get__和__set__的对象是数据描述符。
当使用实例对象访问属性时,都会调用__getattribute__()方法,该方法查找属性的优先级如下:
类属性à数据描述符à实例属性à非数据描述符à__getattr__()方法
①在类属性(包括祖先类)中查找数据描述符,如找到,则直接调用该数据描述符的__get__方法并将结果返回;
②若未找到,则在实例的__dict__中查找属性;
③在类(包括祖先类)的__dict__属性中查找非数据描述符
普通函数(包括函数、静态/类方法)都是非数据描述符,可被实例属性覆盖。
class C(object):
def __init__(self, name):
self._name=name
def __get__(self, obj, typ=None):
return self.name
def __set__(self, obj, value):
self._name=value
class Test(object):
name=C()
test=Test()
test.name='123' # 调用__set__()方法
1.7.4 枚举类
①Enum
from enum importEnum
month=Enum('month',('JAY','FEB','MAR','APR'))
print(month.JAY) #返回month.JAY
type(month.JAY) # <enum 'month'>
print(month.JAY.value) #返回1。int,默认从1开始
forname, member in Month.__members__.items(): #遍历
print(name, '=>', member, ',',member.value) #第一个是JAY => month.JAY, 1
②@unique
检查保证没有重复值.
@unique
class Weekday(Enum):
Sun = 0 # Sun的value被设定为0
Mon = 1
Tue = 2
Wed = 3
Weekday.Tue #Weekday.Tue
Weekday['Tue'] #Weekday.Tue
Weekday(2) #Weekday.Tue
1.7.5 定制类
__str__():
在类中实现该方法,return一个自定义的显示字符串,调用print()和str()时将会显示该字符串。
__repr__():
交互界面直接输入变量名,输出的结果是调用repr()的结果,用于调试服务。
在类中可以直接写__repr__ = __str__
__iter__():
返回一个迭代对象,使对象可以用于iter()内建函数。不断调用该迭代对象的__next__()方法,返回下一个值,直到StopIteration错误时退出循环。对于自定义的迭代器,只需返回自身self。
__next__():
实现该方法就是一个迭代器。
def __next__(self):
self.a, self.b =self.b, self.a + self.b # 计算下一个值
if self.a > 100000:# 退出循环的条件
raiseStopIteration()
return self.a # 返回下一个值
__getitem__(self, n):
使能够像list那样按照下标取出下标为n的元素。
__setitem__( self, n):
把对象视作list或dict来对集合赋值。
__delitem__( self, n):
用于删除某个元素。
__getattr__(self, attr):
当调用实例的不存在的属性,将尝试调用该方法,动态返回一个值。若尝试该函数和实例中未定义的其他属性,则会返回None。对于其他未定义的属性,可以抛出异常。raise AttributeError('xxxxxxxxxx').
__call__():
使实例可以像函数一样,成为一个可调用callable对象。可以定义参数,调用时执行该特殊方法下的内容。
如c=C(); c() #将执行__call__()。
callable()内置函数可以判断是否是可调用对象。
__nonzero__(self):用于内建函数bool(), 定义转为布尔值的方法。
__len__(self):用于内建函数len(),求取对象“长度”。
数值定制用的特殊方法:__add__(self, other)、__mul__(self, num):- Python3学习笔记(7)—— 面向对象编程
- Python3面向对象编程笔记(一)
- Python3学习笔记6-类,面向对象编程
- Python3.5——面向对象编程
- Python学习笔记 7—面向对象编程
- Python3.X之面向对象编程笔记
- Python学习笔记(六)——面向对象编程
- 我的Python3学习笔记(3):面向对象
- Python3 面向对象编程
- python2.7学习笔记(9) ——面向对象编程
- python2.7学习笔记(10) ——面向对象高级编程
- 面向对象编程小结(学习笔记)
- Python3 基础:面向对象编程(上)
- Python3 基础:面向对象编程(下)
- python3面向对象编程一(类)
- C++ Primer学习笔记——$15 面向对象编程
- 《Java面向对象编程》学习笔记12——计数器
- C++ Primer学习笔记——$15 面向对象编程
- Java中Set集合 Iterator迭代遍历数组
- linux jdk 安装
- java8 List和Map遍历
- 数据容灾技术比较
- RabbitMQ消息队列(五):Routing 消息路由
- Python3学习笔记(7)—— 面向对象编程
- Redhat7.X 安装报错 /dev/root does not exits
- Unity_宠物跟随效果_058
- request代理问题
- 51nod 1007 正整数分组
- 欧拉回路
- 在linux 和 ubuntu下运行itchat,怎样看见二维码?
- sql server的具体安装教程
- 《笨办法学python》加分习题17——我的答案