目录
面向对象编程——Object Oriented Programming,简称 OOP,把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
类:在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念
封装:封装实际上是把数据封装到某个地方, 以后再去调用被封装在某处的内容或者数据。封装的另一个好处是可以给类增加新的方法;
多态:当父类和子类有相同的方法时, 调用优先执行子类的方法;
面向对象编程——Object Oriented Programming,简称 OOP,把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。
类:在Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)的概念
定义一个类:
class Animals(object): ##类的格式(父类):
#类的属性
name = "tom"
age = 12
weight=10
def eat(self): ### 类的方法 ==== 函数,在类中定义的函数叫做方法 ;self 实质上是类实例化后的对象本身 ;
print "eating..."
cat = Animals() ### 类的实例化:产生的就是对象; 把抽象的类创造出实际存在的事物;
print cat
cat.eat() ##调用类的方法
-面向对象的三大特性:封装,继承,多态
封装:封装实际上是把数据封装到某个地方, 以后再去调用被封装在某处的内容或者数据。封装的另一个好处是可以给类增加新的方法;
class Animals(object):
def __init__(self,name,age,weight):
##__init__构造方法,传递name,age,weight必选参数
self.name=name
self.age=age
self.weight=weight
def eat(self):
##__init__ 方法的第一个参数永远是self,表示创建的实例本身,因此,在__init__ 方法内部,就可以把各种属性绑定到sel,因为 self 就指 向创建的实例本身。
print "eating"
self.weight+=0.5
dog = Animals("haski",3,8)
print dog.name
print dog.weight
dog.eat()
print dog.weight
输出:
对象可以实例化多个:
class Animals(object):
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.weight=weight
def eat(self):
print " %s is eating..." %(self.name)
self.weight+=0.5
def drink(self):
print "%s is drinking..." %(self.name)
self.weight +=0.3
dog = Animals("haski",3,8)
tom =Animals("tom",4,6)
dog.eat()
print dog.weight
tom.drink()
print tom.weight
输出:
应用练习一
创建一个类People,拥有的方法为砍柴,娶媳妇,回家;
实例化对象,执行相应的方法
显示如下:
老李,18岁,男,开车去娶媳妇
校思浩,22岁,男,上山去砍柴
唐浩,10岁,女,辍学回家
答案:
class People(object):
def __init__(self,name,age,gender):
self.name=name
self.age=age
self.gender=gender
def goHome(self):
print "%s,%s岁,%s,辍学回家" %(self.name,self.age,self.gender)
def kanChai(self):
print "%s,%s岁,%s,上山去砍柴" %(self.name,self.age,self.gender)
def quXiFu(self):
print "%s,%s岁,%s,开车去娶媳妇" % (self.name, self.age, self.gender)
laoli = People("老李",18,"男")
xiaosihao =People("校思浩",22,"男")
tanghao = People("唐浩",10,"女")
laoli.quXiFu()
xiaosihao.kanChai()
tanghao.quXiFu()
输出:
应用练习二
栈的数据结构:
栈的方法:
入栈(push), 出栈(pop), 栈顶元素(top),
栈的长度(lenght), 判断栈是否为空(isempty)
显示栈元素(view)
操作结果:
栈类的实例化
入栈4次
出栈1次
显示最终栈元素
class Stack(object):
def __init__(self):
stack=[]
self.stack = stack
def push(self,value): ##入栈
self.stack.append(value)
def pop(self): ##出栈
if not self.isempty():
return self.stack.pop()
else:
return None
def top(self): ##栈顶元素
if not self.isempty():
return self.stack[-1]
else:
return None
def lenth(self): ##栈的长度
return len(self.stack)
def view(self): ##显示栈元素
for i in self.stack:
print i,
def isempty(self): ##判断是否为空
return self.stack == []
if __name__ == "__main__":
stack1 = Stack()
item1 = raw_input("Stack input:")
stack1.push(item1)
stack1.push(2) ##模拟队列输入
stack1.push(3)
stack1.push(7)
stack1.pop() ##出栈
print "stack output:"
stack1.view()
输出:
队列的数据结构
队列的方法:
入队(enqueue), 出队(dequeue), 队头元素(head), 队尾元素(tail),
队列的长度(lenght), 判断队列是否为空(isempty)
显示队列元素(view)
操作结果:
队列类的实例化
入队5次
出栈1次
显示最终队列元素
class Queue(object):
def __init__(self):
self.que = []
def enqueue(self,value): ##入队
self.que.append(value)
def dequeue(self): ##出队
if not self.isempty():
return self.que.pop(0)
else:
return None
def top(self): ##队头元素
if not self.isempty():
return self.que[0]
else:
return None
def tail(self):
if not self.isempty():
return self.que[-1]
else:
return None
def lenght(self): ##队的长度
return len(self.que)
def view(self): ##显示队元素
for i in self.que:
print i,
def isempty(self): ##判断是否为空
return self.que == []
if __name__ == "__main__":
que1 = Queue()
item1 = raw_input("queue input:")
que1.enqueue(item1)
que1.enqueue(1)
que1.enqueue(3)
que1.enqueue(4)
print "queue output:"
print que1.top()
que1.view()
输出:
继承:在面向对象程序设计中,当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类。继承最大的好处是子类获得了父类的全部功能
基于继承的栈和队列数据结构实现方法:
class Base(object):
def __init__(self):
self.struct=[]
def length(self):
return len(self.struct)
def view(self):
for i in self.struct:
print i,
class Stack(Base):
def push(self,value): ##入栈
self.struct.append(value)
def pop(self): ##出栈
if not self.isempty():
return self.struct.pop()
else:
return None
def top(self): ##栈顶元素
if not self.isempty():
return self.struct[-1]
else:
return None
def isempty(self): ##判断是否为空
return self.struct == []
if __name__ == "__main__":
stack1 = Stack()
item1 = input("Stack input:")
stack1.push(item1)
stack1.push(2)
stack1.push(3)
stack1.push(4)
print "stack output:"
print stack1.top()
stack1.view()
class Queue(Base):
def enqueue(self,value): ##入队
self.struct.append(value)
def dequeue(self): ##出队
if not self.isempty():
return self.struct.pop(0)
else:
return None
def top(self): ##队头元素
if not self.isempty():
return self.struct[0]
else:
return None
def tail(self):
if not self.isempty():
return self.struct[-1]
else:
return None
def view(self): ##显示队元素
for i in self.struct:
print i,
def isempty(self): ##判断是否为空
return self.struct == []
if __name__ == "__main__":
que1 = Queue()
item1 = raw_input("queue input:")
que1.enqueue(item1)
que1.enqueue(1)
que1.enqueue(3)
que1.enqueue(4)
print "queue output:"
print que1.top()
que1.view()
输出:
#Animals 是父类/基类;
class Animals(object):
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.weight=weight
def eat(self):
print "eating"
self.weight+=0.5
def drink(self):
print "%s is drinking....." %(self.name)
self.weight +=1
#Dog 是Animalde 子类/派生类
class Dog(Animals):
def shut(self):
print "%s wang wang...." %(self.name)
class Cat(Animals):
def sleep(self):
print "%s is sleeping " %(self.name)
tom = Dog("tom",3,8)
tom.eat()
tom.shut()
print tom.weight
harry = Cat("harry",4,6)
harry.sleep()
harry.drink()
print harry.weight
重写父类构造函数
原始父类构造写法:
class Animals(object):
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.weight=weight
def eat(self):
print "eating"
self.weight+=0.5
def drink(self):
print "%s is drinking....." %(self.name)
self.weight +=0.3
class Dog(Animals):
def __init__(self,name,age,weight,dogid):
self.name=name
self.age=age
self.weight=weight
self.dogid=dogid
def shut(self):
print "%s wang wang...." %(self.name)
class Cat(Animals):
def __init__(self,name,age,weight,food):
self.name=name
self.age=age
self.weight=weight
self.food=food
def sleep(self):
print "%s is sleeping " %(self.name)
tom = Dog("tom",3,8,"001")
tom.eat()
tom.shut()
print tom.weight
print tom.dogid
harry=Cat("harry",4,6,"fish")
harry.drink()
print harry.weight
print harry.food
输出:
### 重写父类的构造函数
父类名.__init__(self,形参)
super(自己类的名称, self).__init__(形参)
- 不需要明确告诉父类的名称;
- 如果父类改变,只需修改class语句后面的继承关系即可;
当父类和子类拥有共同属性时:可以通过下列方法实现较为简单的写法
方法一:
class Dog(Animals):
def __init__(self, name, age, weight, dogid):
Animals.__init__(self, name, age, weight)
self.dogid = dogid
def shut(self):
print "%s wang wang......" %(self.name)
方法二:
class Dog(Animals): ##当父类改变时只需要修改传入的对象
def __init__(self,name,age,weight,dogid):
self.dogid = dogid
super(Dog, self).__init__(name, age, weight)
def shut(self):
print "%s wang wang...." %(self.name)
效果和原函数一样
多态:当父类和子类有相同的方法时, 调用优先执行子类的方法;
当子类和父类都存在相同的 方法时,我们说,子类的覆盖了父类的,在代码运行的时候,总是会调用子类的继承的另一个好处:多态,
class Zoom():
pass
class Animals(object):
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.weight=weight
def eat(self):
print "eating"
self.weight+=0.3
class Cat(Animals):
def eat(self):
print "%s eating..." %(self.name)
self.weight +=0.4
class Dog(Animals,Zoom):
def eat(self):
print "%s eating..." % (self.name)
self.weight += 0.5
haski = Dog("haski", 3, 3)
haski.eat()
print haski.weight
输出:
特殊类的属性:
#打印函数名称,打印函数doc文档
print Animals.__name__
print Animals.__doc__
# 打印类的所有父类,以元组类型返回;
print Animals.__bases__
print Dog.__bases__
输出:
#以字典的方式返回类的方法和属性;
print Animals.__dict__
输出:
{'__module__': '__main__', 'eat': <function eat at 0x7f929606caa0>, '__dict__': <attribute '__dict__' of 'Animals' objects>, '__weakref__': <attribute '__weakref__' of 'Animals' objects>, '__doc__': '\n \xe7\x88\xb6\xe7\xb1\xbbAnimals:\n Attritube:\n name:\n age:\n weight:\n ', '__init__': <function __init__ at 0x7f929606ca28>}
实现查看类实例化对象的个数
# ##类属性
class Info(object):
a = 1
## 类属性,在内存中只存一份;
country="China"
def __init__(self,name):
### 构造函数里面的属性存的份数取决于你的对象个数;
self.name =name
p1 =Info("p1")
print p1.country
p2 = Info("p2")
print p2.country
统计多个类实例化对象的个数
class Info(object):
count =0
def __init__(self):
Info.count += 1
a = Info()
b = Info()
c = Info()
print Info.count
del a
print Info.count
输出:
3
2
普通方法,类方法,静态方法
普通方法:
class Date(object):
def __init__(self,year,month,day):
self.year =year
self.month =month
self.day =day
def echo_date(self):
print """
Year:%s
Moth:%s
Day:%s
""" %(self.year,self.month,self.day)
def str_date(s): ##普通方法
year,month,day=map(int,s.split('-'))
d = Date(year,month,day)
d.echo_date()
str_date('2014-2-1')
类方法和静态类方法:
class Date(object):
def __init__(self,year,month,day):
self.year =year
self.month =month
self.day =day
def echo_date(self):
print """
Year:%s
Moth:%s
Day:%s
""" %(self.year,self.month,self.day)
# def str_date(s): ##普通方法
# year,month,day=map(int,s.split('-'))
# d = Date(year,month,day)
# d.echo_date()
# str_date('2014-2-1')
@classmethod ##类方法
def str_date(cls, s):
#(参数为cls类.cls是class的缩写)
year, month, day = map(int,s.split('-'))
d = cls(year, month, day)
return d
# s = '2018-1-4'
@staticmethod ##静态方法
def is_date_legal(s): ##(参数为对象)
year, month, day = map(int, s.split('-'))
return year > 0 and 0 < month <= 12 and 0 < day < 31
d = Date.str_date("2018-1-5")
d.echo_date()
print "legal" if Date.is_date_legal("2018-1-4") else "illegal"
#特殊的实例方法
- __call__当调用对象时自动执行;
- __str__ 当使用print输出对象的时候,只要自己定义了__str__(self)
方法,那么就会打印从在这个方法中return的数据.
__str__
方法需要返回一个字符串,当做这个对象的描写
class Info(object):
def __init__(self):
print "in __init__"
def __call__(self):
print "in __call__"
def __str__(self):
return "in __str__"
def __iter__(self):
pass
a = Info()
a()
# print a
from collections import Iterable
isinstance(a, Iterable)