python(面向对象编程)
自己结合讲师,自己写的笔记。有不足的地方,不足之处希望大家评论指出。大家互相学习。欢迎留言。
面向对象的出现
由一个属性相同的群体,完成一个大的任务。
实例化定义好类后用此类构造出对象(对象可以许多个
init(self)【构造器】
self指是当前实例化对象
python并不是真正的构造器,只是实例的回调,不能带返回)
#定义一个类
class A(object ):#定义类,名称首字母大写,默认()里面为父类
#对象的构建(属性包括数据和方法)
pass
> class P():
> def __init__(self):
> print('+'*20)
>
> def __init__(self,name,age):
> self.name=name
> self.age=age
>
> def run(self):
> pass
>
> if __name__=='__main__':
> p=P()#实例化
> #p2=P('xxx',20)
方法和函数是不同的class里为方法,实例外的是函数。
python动态语言特性
#定义一个类
class P(object ):#定义类,名称首字母大写,默认()里面为父类
#对象的构建(属性包括数据和方法)
pass
if name==‘main’:
p=P()
p.name=‘name’
p.age=10
print(p.name )
print(p.age )
print(hasattr(p,'name') )#hasatter作用在p上查找name属性
print(hasattr(p,'age') )
p.func=lambda x: x+1
print(p.func (1))
对象实例化调用,调用实例化
#定义一个类
class A(object ):#定义类,名称首字母大写,默认()里面为父类
#对象的构建(属性包括数据和方法)
pass
class P():
def __init__(self,name,age):
self.name=name
self.age=age
def run(self):
print(self .name +'run...')
if __name__=='__main__':
p2=P('xxx',20)#实例化
print(p2 .age)
print(p2 .name)
可变类型和不可变类型区别
#定义一个类
class A(object ):#定义类,名称首字母大写,默认()里面为父类
#对象的构建(属性包括数据和方法)
pass
class P():
has_two_eyes=[]#定义静态的属性
#def func(self):
# print('func invoke...')
def __init__(self,name,age):
self.name=name
self.age=age
def run(self):
print(self .name +'run...')
if __name__=='__main__':
p1=P('p1',1)#实例化对象
p2=P('p2',2)
# print(P .has_two_eyes )
#print(p1.has_two_eyes )
#print(p2.has_two_eyes )
###########################
#P.has_two_eyes +=1#静态属性的更新
#print(P .has_two_eyes )
#########################
#p1 .has_two_eyes +=1
#print(P.has_two_eyes )
#print(p2.has_two_eyes )
#print(p1 .has_two_eyes )
#print(id(P.has_two_eyes ) )
#print(id(p1.has_two_eyes ) )
##########################列表表示.int是不可变,列表是可以改变的类型
p1 .has_two_eyes .append(123)
print(p1 .has_two_eyes )
print(id(P.has_two_eyes ) )
print(id(p1.has_two_eyes ) )
如何定义一个对象(不同实例,用不同的构造器,)
#定义一个类
class Name(object ):#定义类,名称首字母大写,默认()里面为父类
#对象的构建(属性包括数据和方法(脱离构造叫函数))
def init(self,name,age): #构造器(特殊方法)添加属性:名字,年龄(self为当前对象this)
self.name=name #构造属性(如同杯子的模具)
self.age=age
def __del__(self):#类的属性都一样(就是对象有相同的属性:如吃)
print(self .__class__.__name__+'name del')
def eat(self):
print(self .__class__ .__name__+'eat')
def move(self):
print(self .__class__ .__name__ +'move')
封装(属性私有化——>对外提供方法,对属性进行修改)python在模块里面无效,类里有效(类内部’__name’单下划线(私有属性,可以访问),双下划线打头的(私有属性,无法访问)前后都有下划线(特殊属性)
继承(子类可以访问父类属性(前提父类公开)
#定义一个类
1、python是多继承实现机制
2、如果多个父类中存在重名的方法时,自类对象调用时的顺序问题
python2:
|-- 新式类
广度优先继承
|-- 旧式类(经典类)
深度优先继承
python3
只有新式类
class Name(object ):#定义类,名称首字母大写,默认()里面为父类
#对象的构建(属性包括数据和方法)
def __init__(self,name,age): #构造器构建实例(特殊方法)添加属性:名字,年龄(self为当前对象this)
self.name=name #构造属性(如同杯子的模具)
self.age=age
def __del__(self):#类的属性都一样(就是对象有相同的属性:如吃)
print(self .__class__.__name__+'name del')
def eat(self):
print(self .__class__ .__name__+'eat')
def move(self):
print(self .__class__ .__name__ +'move')
def sleep(self):
print(self .__class__ .__name__ +'sleep')
class Person(Name ):#Persin继承Name(继承有属性,但有不同,有区分)
#非绑定方法
def __init__(self,name,age,sex):
Name.__init__(self, name, age) # 子类调用父类的构造方法
self .sex=sex#多的属性区分父类
def think(self):
print(self .__class__ .__name__ +'think')
def wear(self):
print(self.__class__.__name__ + 'wear')
if __name__=='__main__':
#a=Name('青蛙',2)#参考定义的构造器规划,实现对象的实例化
#print('name=%s'%a.name )
#print('age=%d'%a.age )
#a.sleep()#aelp不需要传递,解释器自动完成
#a.eat()
#a.move()
b=Person ('人',30,'男')#实例化对象
print(b.name )#自己独特的属性
print(b.age )
print(b.sex )
b.eat()#继承的属性
b.move()
b.sleep()
重写(overwrite)|覆盖(override)
重写(override)和重载(overload)的区别?
(重载:函数名称相同,参数类型或者个数不同)
重载:函数
python中不存在重载
多态与继承
#定义一个类
class P(object ):#定义类,名称首字母大写,默认()里面为父类
#对象的构建(属性包括数据和方法)
def __init__(self,name,age):
self.name=name
self.age=age
def run(self):
print('P run...')
class C(P):
def __init__(self,name,age,sex):
P.__init__(self ,name,age )#传递父类的构造
self. sex=sex
def run(self):
P.run(self ) #子类方法体调用父类方法
print('C run...')#方法的覆盖
if __name__=='__main__':
c=C('child',20,'man')
c.run()#绑定是实例化后的类 ,子类没有可以调用父类。子类有就不会调用父类(多态)
dir()查看类属性
class A():
'''
this is a class
'''
def __init__(self):
pass
if __name__=='__main__':
for item in dir(A ):#将A放出来
print(str (item )+str (getattr(A,item ) ) ) #
查看类对象属性
class A():
'''
this is a class
'''
def __init__(self,name):
self .name=name
if __name__=='__main__':
a=A('name')
#print(dir(a ) )#查看类的属性和对象
print(a .__dict__ )#查看对象属性
子类没有方法时,调用的是父类
class P():
#父类实现构造方法,实例化子类对象时会,调用父类的方法
def __init__(self):
print('p__e')
class A(P ):
pass
if __name__=='__main__':
a=A()
python父类如果实现了构造方法,子类没有,实例化子类对象时会默认调用父类的构造方法
```clike
class P():
def __init__(self):
print('P __init__ invoke...')
class A(P):
def __init__(self):
P.__init__(self)
print('A __init__ invoke...')
if __name__ == '__main__':
a=A()
- 父类方法调用多种方法
class P1():
def __init__(self):
print('P1 __init__ invoke...')
class P2():
def __init__(self):
print('P2 __init__ invoke...')
class A(P1,P2):
def __init__(self):
P1.__init__(self)
P2.__init__(self)
print('A __init__ invoke...')
if __name__ == '__main__':
a=A()
第二种方法super(A,self).init()
class P1():
def __init__(self):
print('P1 __init__ invoke...')
class P2():
def __init__(self):
print('P2 __init__ invoke...')
class A(P2,P1):
def __init__(self):
P1.__init__(self)
P2.__init__(self)
super(A,self).__init__()
print('A __init__ invoke...')
if __name__ == '__main__':
a=A()
+ 静态方式无法访问对象的自身属性变量
```python
class A():
method = 1 # 静态属性
def __init__(self, name):
self.name = name
def run(self):
print('run invoke...')
@staticmethod
def func(x):
print('self.name=%s' % x)
print('func invoke...')
@classmethod
def test(cls):
print('test ...')
print('method=%d'%A.method )#静态的查找
if __name__ == '__main__':
# a=A('name')
# a.run()
# A.func('liwenbo')
# A('xxx').func('yyy')
A.test()
- 方法重载 str
class A(object):
def __init__(self,name,age):
self.name=name
self.age=age
def __str__(self):#方法重载
return 'name=%s,age=%d'%(self.name,self.age)
if __name__ == '__main__':
a=A('liwen',20)
print(a)
+ 重载__iter__和__next__实现一个可迭代的类型(无限循环的版本)
import random
class A():
def __init__(self,seq):
'''seq type(iterable)'''
self.seq=seq
def __iter__(self):
return self#返回当前对象,变成可迭代的对象
def __next__(self):
return self.seq[random.randint(0,len(self.seq)-1)]
if __name__ == '__main__':
a=A([1,2,3])
for item in a:
print(item)
重载__iter__和__next__实现一个可迭代的类型(有限循环的版本)
import random
class A():
def __init__(self,seq):
'''seq type(iterable)'''
self.seq=seq
self.index=0
def __iter__(self):
return self#返回当前对象
def __next__(self):
if self.index > len(self.seq) - 1:
raise StopIteration
else:
tmp = self.seq[self.index]
self.index+=1
return tmp
if __name__ == '__main__':
a=A([1,2,3,50,43])
for item in a:
print(item)
**单链表结构**
```python
#实现一个单链表
#用node来作为链表的节点抽象类
class Node():
def __init__(self,data):
self.data=data
self.next=None
def show(self):
print('node data=%d'%self.data)
def __str__(self):
return 'node data=%s'%self.data
class LinkList():
def __init__(self):
self.head=None
def insertFirst(self,data):
newNode = Node(data)#创建新节点
newNode.next=self.head
self.head = newNode
def deleteFirst(self):
tmpNode= self.head
self.head=self.head.next
return tmpNode
def travel(self):
currentNode = self.head
while currentNode is not None:
print(currentNode)
currentNode = currentNode.next
if __name__ == '__main__':
n1=Node('A')
n2=Node('B')
n3=Node('C')
link=LinkList()
link.insertFirst(n1)
link.insertFirst(n2)
link.insertFirst(n3)
link.travel()
print('+'*30)
link.deleteFirst()
link.deleteFirst()
link.deleteFirst()
link.travel()
子类覆盖父类达到改变父类默认行为
class Mr(dict ):#子类覆盖父类方法
def keys(self):
return sorted(super(Mr,self).keys(),reverse=False)#super父类方法调用
if __name__=='__main__':
w=Mr({'a':1,'b':2})
print(w.keys())
子类继承不可变父类(达到改变父类不可变的行为)
class WrapperFloat(float):#改变父类不可变变量,保留小数点后二位。
def __init__(self,val):#禁止返回return
self.val=val
print('__init__')
def __new__(cls,val):
#return float.__new__(cls,round(val,2))
return super(WrapperFloat, cls ).__new__(cls,round(val,2))#方法2
if __name__=='__main__':
w=WrapperFloat(3.0098)
print(w )
类的slots应用(保护属性)
class A():
__slots__ = 'name','age'#定义了类的属性名称,不允许增加和修改
def __init__(self,name):
self.name=name
if __name__=='__main__':
a=A('li')
a.app()