面向过程,
面向函数,reduce(add,[1,2,3])
面向对象
面向对象的三大特性: 封装, 继承, 多态
先看这个例子
##定义类的过程
class Animal:
##__init__构造函数,当实例化时会自动取调用
##self实质上是实例化的对象本身
def __init__(self,name,age,weight):
##类的属性
self.name=name
self.age=age
self.weight=weight
# 析构函数; 一般用作类的清理工作,自动调用;
def __del__(self):
print "delete........"
##实例化对象的过程 cat使实例化的一个对象,实例化的属性name,age,weight
cat=Animal('fentiao',10,13)
print cat.name
print cat.age
print cat
---->>结果
fentiao
10
13
<__main__.Animal instance at 0x7fb31c2033f8>
delete........
定义一个类
经典类的格式python2.x
class 类名:
def __init__(self):self后可以跟类的属性
变量名=类名(添加类的属性)
类名后面有括号的类,称为新式类;python2.xpython3.x
括号里面的内容是父类的名称;程序中,所有类的父类都是 object;
class Animals(object):
pass
print Animals
<class '__main__.Animals'>
方法的调用,一般方法函数名建议使用动词
类的方法 ==== 函数在类中定义的函数叫做方法 ;
类的方法中, python 解释器要求第一个形参必须是 self
import random
import time
class Animal:
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.weight=weight
def eat(self):
print 'eating...'
time.sleep(random.random())
self.weight+=1
print "%s now weight:%s" %(self.name,self.weight)
def play(self):
print 'playing...'
time.sleep(random.random())
self.weight-=1
print "%s now weight:%s" % (self.name, self.weight)
def __del__(self):
print '清理中...'
cat = Animal('fentiao',10,12)
print cat.name , cat.age,cat.weight
cat.eat()
cat.play()
del cat
---->>结果
fentiao 10 12
eating...
fentiao now weight:13
playing...
fentiao now weight:12
清理中...
封装,封装实际上是把数据封装到某个地方, 以后再去调用被封装在某处的内容或者数据;
封装数据
调用封装数据
通过对象直接调用;
通过self间接调用
class People():
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,'男')
laoli.quXiFu()
xiao=People('校思浩',22,'男')
xiao.kanChai()
tang=People('唐浩',10,'女')
tang.goHome()
继承
-父类和子类; 基类和派生类;
-注意: 类的属性名和方法名不同相同;
-建议:
-属性名用名词;eg:name, age, weight;
-方法名建议用动词; eg: eat, drink, get_weight;
第一种情况,子类不存在__init__函数
class Animal(object):
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.weight=weight
def eat(self):
print 'eating...'
def play(self):
print 'playing...'
##Cat: 子类,/派生类; Animal:父类/基类;
# 子类不存在__init__函数, 调用父类的;
# 子类存在__init__函数, 调用子类的;
class Cat(Animal):
pass
jumao = Cat('jumao',12,14)
print jumao
jumao.play()
---->>
<__main__.Cat object at 0x7f387cb14f50>
playing...
第二种情况:存在__init__函数,执行报错,子类Cat存在__ini__函数,而且参数有两个self和country,很明显子类没有调用Animal父类,
如果子类存在构造函数有想调用父类构造函数怎么办?第一种继承方法:可维护性低
-Animal.init(self,name,age,weight)
class Animal(object):
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.weight=weight
def eat(self):
print 'eating...'
def play(self):
print 'playing...'
class Cat(Animal):
def __init__(self,name,age,weight,country):
Animal.__init__(self,name,age,weight)
self.name = name
self.age = age
self.weight = weight
self.country=country
jumao = Cat('jumao',12,14,'CHINA')
print jumao.name,jumao.age,jumao.country
jumao.play()
---->>
jumao 12 CHINA
playing...
第二种继承方法:可维护性高
class Animal(object):
def __init__(self,name,age,weight):
self.name=name
self.age=age
self.weight=weight
def eat(self):
print 'eating...'
def play(self):
print 'playing...'
class Cat(Animal):
def __init__(self,name,age,weight,country):
super(Cat,self).__init__(name,age,weight)
self.country=country
jumao = Cat('jumao',12,14,'CHINA')
print jumao.name,jumao.age,jumao.country
jumao.play()
--->>
jumao 12 CHINA
playing...
多继承
新式类多继承时, 继承算法是广度优先; 查看方式A.mro()
A - (B,C) -D
经典类多继承时, 继承算法是深度优先;
新式类
class D(object):
def test(self):
print "D test"
class C(D):
def test(self):
print "C test"
class B(D):
pass
# def test(self):
# print "B test"
class A(B,C):
pass
# def test(self):
# print "A test"
a=A()
a.test()
print A.mro()
--->>结果:A首先继承B的属性,但是B此时为空,没有构造函数,与时去继承C,最后执行C的__init__函数,A.mro()是继承的一个顺序
C test
[<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <type 'object'>]
经典类:没有*.mro()属性
class D():
def test(self):
print "D test"
class C(D):
def test(self):
print "C test"
class B(D):
pass
# def test(self):
# print "B test"
class A(B,C):
pass
# def test(self):
# print "A test"
a=A()
a.test()
--->>结果,A没有构造函数,所以第一时间会去继承B的构造函数,B为空,接着深度挖掘去继承B的父类D的属性,
D test
多态:当父类和子类有相同的方法时, 调用优先执行子类的方法;
实验说明1:子类和父类doc方法共存,调用子类doc方法
class Student(object):
def __init__(self,name='xiaoming',score=300):
self.name=name
self.__score = score
def doc(self):
print '这时父类doc方法'
class MathStudnet(Student):
pass
def doc(self):
print '这时子类doc方法'
a=MathStudnet('xiaoli',50)
print a.name
a.doc()
---->>结果
xiaoli
这时子类doc方法
实验说明2:子类无doc方法共存,调用父类doc方法
class Student(object):
def __init__(self,name='xiaoming',score=300):
self.name=name
self.__score = score
def doc(self):
print '这时父类doc方法'
class MathStudnet(Student):
pass
a=MathStudnet('xiaoli',50)
print a.name
a.doc()
---->>结果:
xiaoli
这时父类doc方法
类属性(一)
class Animal(object):
"""Animal class"""
pass
print Animal.mro()
print Animal.__name__
print Animal.__bases__
print Animal.__doc__,'\n'
print "*"*20+"分割线"+"*"*20,'\n'
cat = Animal()
print cat.__class__
print cat.__module__
---->>结果:
[<class '__main__.Animal'>, <type 'object'>]
Animal
(<type 'object'>,)
Animal class
********************分割线********************
<class '__main__.Animal'>
__main__
关于module
在Package/package01/module01中定义Animal新式类
在modelu02中导入该模块,查看cat类模块名
两个特别的函数(魔术函数):__repr__(self):和__str__(self):
__repr__(self):调试时自动调用,__str__(self):打印对象时自动调用
class Animal(object):
def __init__(self,name):
self.name = name
def __repr__(self):
"""
调试时自动调用, a = Animal("xxx") a
:return:
"""
return "Animals:%s" %(self.name)
def __str__(self):
"""打印对象时,自动调用"""
return "%s" %(self.name)
a = Animal('fentiao')
print a
实验:
class Animal(object):
def __init__(self,name):
self.name=name
def __repr__(self):
return '据说调试时自动调用它__repr__(self)'
def __str__(self):
return '据说打印时自动调用它__str__(self):'
dog = Animal('habagou')
print dog
---->>结果
据说打印时自动调用它__str__(self):