python是函数式的编程语言,也是面向对象的编程语言,在python中,解释器的执行顺序是从上到下,定义类的关键字是
class,其中类名字的首字是大写,在python中,面向对象执行的步骤为:
1、定义类
class class_name:
def 方法名(self):
pass
2、依据类创建创建对象或者说创建对类进行实例化,使用对象去执行类中的方法
3、在类的方法中,self是形式参数,在python的内部进行传递。
如下我们定义一个类,来看类的定义以及它的使用
class F:
def __init__(self,name):
self.name=name
def getName(self):
return self.name
def setName(self,name):
self.name=name
def info(self):
print 'my name is {0}'.format(self.name)
def __del__(self):
print u'执行结束...'
在如上的类中,__init__是构造方法,__del__是析构方法,在一个python的类当中,类都是具有构造方法的,它的执行顺序是对类
进行实例化的对象后,调用类中的方法,是先执行构造方法,再执行类中的方法,再执行析构方法,比如我们调用info()方法,来看
类执行的顺序,见实现的代码和执行顺序的结果:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class F:
def __init__(self,name):
self.name=name
print u'类开始执行...'
def getName(self):
return self.name
def setName(self,name):
self.name=name
def info(self):
print 'my name is {0}'.format(self.name)
def __del__(self):
print u'执行结束...'
f=F(u'无涯')
print f.info()
见该代码执行后的输出内容:
C:\Python27\python.exe D:/git/Python/Day/day1/index.py
类开始执行...
my name is 无涯
None
执行结束...
依据如上我们可以看到,执行的顺序是先执行__init__,下来执行info方法,最后执行__del__方法。
构造方法在某些时候,可以理解为是对对象的另外一种封装的方式,一个类进行实例化的时候,如果它的构造方法的参数是什么,
对类进行实例化的时候,得填写相应的参数,比如我们定义如下的类,它的构造方法的参数是名字,年龄,地址,地址默认是西安,
我们然后输出这些信息,见该类的代码和它的输出:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class F:
def __init__(self,name,age,address='西安'):
self.name=name
self.age=age
self.address=address
def show(self):
return 'my name is :{0} , and my age is:{1},and my address is:{2}'.format(self.name,self.age,self.address)
f=F('无涯',20)
print f.show()
见执行如上的代码后输出的内容:
C:\Python27\python.exe D:/git/Python/Day/day1/index.py
my name is :无涯 , and my age is:20,and my address is:西安
Process finished with exit code 0
在python的类中,一个类可以继承单个类,也可以继承多个类,下面我们首先来看python类的继承实现的方式,
定义一个动物类,每个动物都有名字,每个动物只是有不同的属性,比如狗是汪汪,小猫是喵~,那么对于狗和猫
来说,它都需要名字,就不需要单独的写方法了,直接继承动物的类,下面我们来实现这样的一个过程,见代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Animal(object):
def __init__(self,name):
self.name=name
def eat(self):
print '{0}开始吃饭...'.format(self.name)
def drink(self):
print '{0}开始喝水...'.format(self.name)
class Dog(Animal):
def __init__(self,name):
Animal.__init__(self,name)
def wang(self):
print '{0}汪汪的叫'.format(self.name)
class Cat(Animal):
def __init__(self,name):
Animal.__init__(self,name)
def jiao(self):
print '{0}喵喵的叫'.format(self.name)
dog=Dog('狗')
dog.eat()
dog.drink()
dog.wang()
cat=Cat('猫')
cat.eat()
cat.drink()
cat.jiao()
如上的类中,不管是狗还是猫,它都得吃饭和喝水,我们写在Animal类中,直接继承它调用就可以了,在面向对象中,
Animal叫父类,也叫基类,Dog和Cat叫子类,也叫派生类。派生类可以继承基类中所有的功能,派生类和基类同时存
在,优先找派生类,我们通过一个案例来实现这样的一个过程,见代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Animal(object):
def __init__(self,name):
self.name=name
def eat(self):
print '{0}开始吃饭...'.format(self.name)
def drink(self):
print '{0}开始喝水...'.format(self.name)
class Dog(Animal):
def __init__(self,name):
Animal.__init__(self,name)
def wang(self):
print '{0}汪汪的叫'.format(self.name)
def drink(self):
print '小狗开始喝水了,哈哈哈哈'
dog=Dog('狗')
dog.eat()
dog.drink()
在如上的代码中,父类和子类都存在drink的方法,也就是说子类对父类的drink()方法进行了覆写,那么调用的时候,
调用的是父类的方法了还是子类的方法了,答案肯定是子类的方法,见执行的输出内容:
C:\Python27\python.exe D:/git/Python/Day/day1/index.py
狗开始吃饭...
小狗开始喝水了,哈哈哈哈
Process finished with exit code 0
如上我们说到,在python中,一个类可以继承N个类,那么它执行顺序是怎么样的,其实它执行的顺序是:优先从自己找,如果
自己没有,从继承的类从左到右进行寻找,我们来看这样的一个过程,见实现的代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Animal1(object):
def drink(self):
print '第一个类的方法开始执行'
class Animal2(object):
def drink(self):
print '第二类的方法开始执行'
class Dog(Animal1,Animal2):
def drink(self):
print '小狗开始喝水了,哈哈哈哈'
dog=Dog()
dog.drink()
如上的代码执行后,执行的是子类Dog中的drink()方法,下面再来看继承的类从左到右的执行顺序案例代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Animal1(object):
def drink(self):
print '第一个类的方法开始执行'
class Animal2(object):
def drink(self):
print '第二类的方法开始执行'
class Dog(Animal1,Animal2):
pass
dog=Dog()
dog.drink()
如上的代码执行后,执行的是Animal1类中的drink()方法,见输出的结果内容:
C:\Python27\python.exe D:/git/Python/Day/day1/index.py
第一个类的方法开始执行
Process finished with exit code 0
下面利用结合反射和类,来查找类中的方法是否存在,具体见如下实现的代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Obj(object):
def __init__(self,name):
self.name=name
def show(self):
pass
obj=Obj('wuya')
print u'通过反射获取成员名称:',getattr(obj,'name')
print u'通过反射查看类中的方法是否存在:',hasattr(obj,'show')
print u'通过反射查看类中的成员名称是否存在:',hasattr(obj,'name')
见如上的代码执行后的结果:
C:\Python27\python.exe D:/git/Python/Day/day1/index.py
通过反射获取成员名称: wuya
通过反射查看类中的方法是否存在: True
通过反射查看类中的成员名称是否存在: True
Process finished with exit code 0
下面通过反射结合模块来查找类中的方法是否存在,以及获取类成的成员名称,也就是说我们在OOP.py的模块
编写了一个类,类中有方法,我们在index.py模块中,结合反射的方式来判断该模块中的类方法是否存在,获取
类中的成员变量结果,OOP.py的代码为:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Obj(object):
def __init__(self,name):
self.name=name
def show(self):
pass
index.py模块的代码为(该代码实现获取OOP.py模块中的类,然后判断方法和获取类成员方法),见代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
def exists(moduleName,className):
m=__import__(moduleName,fromlist=True)
#判断模块中的类是否存在
if hasattr(m,className):
#获取模块中的类
class_name=getattr(m,className)
#实例化类
obj=class_name('wuya')
print u'通过反射获取类中的成员方法:',getattr(obj,'name')
print u'通过反射判断类中的show()方法是否存在:',hasattr(obj,'show')
else:
print u'Sorry,类不存在'
exists('OOP','Obj')
在python的面向对象编程中,存在静态成员这么一个说法,静态字段,简单的理解就是在一个对象中,把每一个重复的东西
类中只存在一份,我们来看一个简单的案例,打印每个省份,每个省份它有一个共同的对象,就是china,那么我们可以把china定
义为类的静态字段,见实现的案例代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Province(object):
country='china'
def __init__(self,name):
self.name=name
def show(self):
print u'国籍:{0},属于哪个省:{1}'.format(self.country,self.name)
per=Province(u'台湾')
per.show()
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Province(object):
country='china'
def __init__(self,name):
self.name=name
def show(self):
print u'国籍:{0},属于哪个省:{1}'.format(self.country,self.name)
per=Province(u'台湾')
per.show()
见代码执行后的结果:
C:\Python27\python.exe D:/git/Python/FullStack/Study/oopTest.py
国籍:china,属于哪个省:台湾
Process finished with exit code 0
静态字段,其实使用类也可以直接的调用,比如上面的,我们可以使用Province.country这样来调用,它的输出结果是台湾,静态字段属于类,
那么既然存在静态字段,是否存在动态字段了,我们叫普通字段,普通字段属于对象,我们接着上面的例子定义一个普通字段,来演示下静态
字段字段以及普通字段的调用,见案例代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Province(object):
#静态字段,属于类
country='china'
def __init__(self,name):
#普通字段,属于对象
self.name=name
p=Province(u'台湾')
#调用静态字段
print u'类的静态字段是:',Province.country
print u'对象的普通字段是:',p.name
见执行如上的代码后的结果:
C:\Python27\python.exe D:/git/Python/FullStack/Study/oopTest.py
类的静态字段是: china
对象的普通字段是: 台湾
Process finished with exit code 0
在类中,方法有普通方法,静态方法,以及类方法,下面我们分别来看这些方法是怎么编写以及如何调用的,这些方法和类,以及对象
之间的关系是什么?见案例代码:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Province(object):
#静态字段,属于类
country='china'
def __init__(self,name):
#普通字段,属于对象
self.name=name
def show(self):
print u'我就是个普通方法'
@staticmethod
def f1():
print u'我是静态方法,我存在的意义就是类不需要创建对象就可以直接调用'
@classmethod
def f2(cls):
print u'我是类方法'
在上面的例子中定义了普通方法,静态方法,以及类方法,那么对它进行分类,普通方法它是属于对象,类方法以及静态方法
它是属于类,由类直接调用,而普通方法需要对象去调用,这样我们可以总结为:类调用静态字段,静态方法,以及类方法,
对象调用普通字段,普通方法,我们对如上的代码进行构造进行调用下,看执行的结果:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Province(object):
#静态字段,属于类
country='china'
def __init__(self,name):
#普通字段,属于对象
self.name=name
def show(self):
print u'我就是个普通方法'
@staticmethod
def f1():
print u'我是静态方法,我存在的意义就是类不需要创建对象就可以直接调用'
@classmethod
def f2(cls):
print u'我是类方法'
p=Province(u'无涯')
print u'对象调用普通字段:',p.name
print u'对象调用普通方法:',p.show()
print u'类调用静态字段:',Province.country
print u'类调用静态方法:',Province.f1()
print u'类调用类方法:',Province.f2()
print u'静态字段也可以被对象调用:',p.country
见如上的代码执行后的结果:
C:\Python27\python.exe D:/git/Python/FullStack/Study/oopTest.py
对象调用普通字段: 无涯
对象调用普通方法: 我就是个普通方法
None
类调用静态字段: china
类调用静态方法: 我是静态方法,我存在的意义就是类不需要创建对象就可以直接调用
None
类调用类方法: 我是类方法
None
静态字段也可以被对象调用: china
Process finished with exit code 0
特性方法,也就是说在一个类中,该方法不能有参数,可以@property,调用特性方法的时候就不需要加()了,我们来编写
一个案例,来进行调用,看执行的结果:
#!/usr/bin/env python
#-*- coding:utf-8 -*-
class Province(object):
#静态字段,属于类
country='china'
def __init__(self,name):
#普通字段,属于对象
self.name=name
def show(self):
print u'我就是个普通方法'
@staticmethod
def f1():
print u'我是静态方法,我存在的意义就是类不需要创建对象就可以直接调用'
@classmethod
def f2(cls):
print u'我是类方法'
@property
def end(self):
print 'name is {0}'.format(self.name)
p=Province('无涯')
p.end
见调用后代码执行的结果:
C:\Python27\python.exe D:/git/Python/FullStack/Study/oopTest.py
name is 无涯
Process finished with exit code