Python之面向对象学习(二十五)

时间:2022-06-19 13:11:10

  python是函数式的编程语言,也是面向对象的编程语言,在python中,解释器的执行顺序是从上到下,定义类的关键字是

class,其中类名字的首字是大写,在python中,面向对象执行的步骤为:

1、定义类

      class class_name:

            def 方法名(self):

                     pass

2、依据类创建创建对象或者说创建对类进行实例化,使用对象去执行类中的方法

3、在类的方法中,self是形式参数,在python的内部进行传递。

如下我们定义一个类,来看类的定义以及它的使用

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'执行结束...'
Python之面向对象学习(二十五)

 

在如上的类中,__init__是构造方法,__del__是析构方法,在一个python的类当中,类都是具有构造方法的,它的执行顺序是对类

进行实例化的对象后,调用类中的方法,是先执行构造方法,再执行类中的方法,再执行析构方法,比如我们调用info()方法,来看

类执行的顺序,见实现的代码和执行顺序的结果:

Python之面向对象学习(二十五)
#!/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()
Python之面向对象学习(二十五)

 

见该代码执行后的输出内容:

C:\Python27\python.exe D:/git/Python/Day/day1/index.py
类开始执行...
my name is 无涯
None
执行结束...

 

依据如上我们可以看到,执行的顺序是先执行__init__,下来执行info方法,最后执行__del__方法。

构造方法在某些时候,可以理解为是对对象的另外一种封装的方式,一个类进行实例化的时候,如果它的构造方法的参数是什么,

对类进行实例化的时候,得填写相应的参数,比如我们定义如下的类,它的构造方法的参数是名字,年龄,地址,地址默认是西安,

我们然后输出这些信息,见该类的代码和它的输出:

Python之面向对象学习(二十五)
#!/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()
Python之面向对象学习(二十五)

 

见执行如上的代码后输出的内容:

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类的继承实现的方式,

定义一个动物类,每个动物都有名字,每个动物只是有不同的属性,比如狗是汪汪,小猫是喵~,那么对于狗和猫

来说,它都需要名字,就不需要单独的写方法了,直接继承动物的类,下面我们来实现这样的一个过程,见代码:

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()
Python之面向对象学习(二十五)

 

如上的类中,不管是狗还是猫,它都得吃饭和喝水,我们写在Animal类中,直接继承它调用就可以了,在面向对象中,

Animal叫父类,也叫基类,Dog和Cat叫子类,也叫派生类。派生类可以继承基类中所有的功能,派生类和基类同时存

在,优先找派生类,我们通过一个案例来实现这样的一个过程,见代码:

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)

    def drink(self):
        print '小狗开始喝水了,哈哈哈哈'

dog=Dog('')
dog.eat()
dog.drink()
Python之面向对象学习(二十五)

 

在如上的代码中,父类和子类都存在drink的方法,也就是说子类对父类的drink()方法进行了覆写,那么调用的时候,

调用的是父类的方法了还是子类的方法了,答案肯定是子类的方法,见执行的输出内容:

C:\Python27\python.exe D:/git/Python/Day/day1/index.py
狗开始吃饭...
小狗开始喝水了,哈哈哈哈

Process finished with exit code 0

 

如上我们说到,在python中,一个类可以继承N个类,那么它执行顺序是怎么样的,其实它执行的顺序是:优先从自己找,如果

自己没有,从继承的类从左到右进行寻找,我们来看这样的一个过程,见实现的代码:

Python之面向对象学习(二十五)
#!/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()
Python之面向对象学习(二十五)

 

如上的代码执行后,执行的是子类Dog中的drink()方法,下面再来看继承的类从左到右的执行顺序案例代码:

Python之面向对象学习(二十五)
#!/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()
Python之面向对象学习(二十五)

 

如上的代码执行后,执行的是Animal1类中的drink()方法,见输出的结果内容:

C:\Python27\python.exe D:/git/Python/Day/day1/index.py
第一个类的方法开始执行

Process finished with exit code 0

      下面利用结合反射和类,来查找类中的方法是否存在,具体见如下实现的代码:

Python之面向对象学习(二十五)
#!/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')
Python之面向对象学习(二十五)

 

见如上的代码执行后的结果:

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的代码为:

Python之面向对象学习(二十五)
#!/usr/bin/env python 
#-*- coding:utf-8 -*-

class Obj(object):
    def __init__(self,name):
        self.name=name

    def show(self):
        pass
Python之面向对象学习(二十五)

 

index.py模块的代码为(该代码实现获取OOP.py模块中的类,然后判断方法和获取类成员方法),见代码:

Python之面向对象学习(二十五)
#!/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之面向对象学习(二十五)

       在python的面向对象编程中,存在静态成员这么一个说法,静态字段,简单的理解就是在一个对象中,把每一个重复的东西

类中只存在一份,我们来看一个简单的案例,打印每个省份,每个省份它有一个共同的对象,就是china,那么我们可以把china定

义为类的静态字段,见实现的案例代码:

Python之面向对象学习(二十五)
#!/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()
Python之面向对象学习(二十五)
Python之面向对象学习(二十五)
#!/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()
Python之面向对象学习(二十五)

 

见代码执行后的结果:

C:\Python27\python.exe D:/git/Python/FullStack/Study/oopTest.py
国籍:china,属于哪个省:*

Process finished with exit code 0

 

静态字段,其实使用类也可以直接的调用,比如上面的,我们可以使用Province.country这样来调用,它的输出结果是*,静态字段属于类,

那么既然存在静态字段,是否存在动态字段了,我们叫普通字段,普通字段属于对象,我们接着上面的例子定义一个普通字段,来演示下静态

字段字段以及普通字段的调用,见案例代码:

Python之面向对象学习(二十五)
#!/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
Python之面向对象学习(二十五)

 

见执行如上的代码后的结果:

C:\Python27\python.exe D:/git/Python/FullStack/Study/oopTest.py
类的静态字段是: china
对象的普通字段是: *

Process finished with exit code 0

 

     在类中,方法有普通方法,静态方法,以及类方法,下面我们分别来看这些方法是怎么编写以及如何调用的,这些方法和类,以及对象

之间的关系是什么?见案例代码:

Python之面向对象学习(二十五)
#!/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'我是类方法'
Python之面向对象学习(二十五)

 

在上面的例子中定义了普通方法,静态方法,以及类方法,那么对它进行分类,普通方法它是属于对象,类方法以及静态方法

它是属于类,由类直接调用,而普通方法需要对象去调用,这样我们可以总结为:类调用静态字段,静态方法,以及类方法,

对象调用普通字段,普通方法,我们对如上的代码进行构造进行调用下,看执行的结果:

Python之面向对象学习(二十五)
#!/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
Python之面向对象学习(二十五)

 

见如上的代码执行后的结果:

Python之面向对象学习(二十五)
C:\Python27\python.exe D:/git/Python/FullStack/Study/oopTest.py
对象调用普通字段: 无涯
对象调用普通方法: 我就是个普通方法
None
类调用静态字段: china
类调用静态方法: 我是静态方法,我存在的意义就是类不需要创建对象就可以直接调用
None
类调用类方法: 我是类方法
None
静态字段也可以被对象调用: china

Process finished with exit code 0
Python之面向对象学习(二十五)

 

     特性方法,也就是说在一个类中,该方法不能有参数,可以@property,调用特性方法的时候就不需要加()了,我们来编写

一个案例,来进行调用,看执行的结果:

Python之面向对象学习(二十五)
#!/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
Python之面向对象学习(二十五)

 

见调用后代码执行的结果:

C:\Python27\python.exe D:/git/Python/FullStack/Study/oopTest.py
name is 无涯

Process finished with exit code