Python系列之反射、面向对象

一、反射

说反射之前先介绍一下__import__方法,这个和import导入模块的另一种方式

1. import  commons
2. __import__(‘commons‘) 

如果是多层导入:

1. from list.text import commons
2. __import__(‘ list.text.commons‘,fromlist=True) #如果不加上fromlist=True,只会导入list目录

反射即想到4个内置函数分别为:getattr、hasattr、setattr、delattr  获取成员、检查成员、设置成员、删除成员下面逐一介绍先看例子:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

class Foo(object):

    def __init__(self):

        self.name = ‘abc‘

    def func(self):

        return ‘ok‘

obj = Foo()

#获取成员

ret = getattr(obj, ‘func‘)#获取的是个对象

= ret()

print(r)

#检查成员

ret = hasattr(obj,‘func‘)#因为有func方法所以返回True

print(ret)

#设置成员

print(obj.name) #设置之前为:abc

ret = setattr(obj,‘name‘,19)

print(obj.name) #设置之后为:19

#删除成员

print(obj.name) #abc

delattr(obj,‘name‘)

print(obj.name) #报错

对于反射小节:

1.根据字符串的形式导入模块。
2.根据字符串的形式去对象(某个模块)中操作其成员 

实例:基于反射实现类Web框架的路由系统

实现思路:规定用户输入格式 模块名/函数名 通过__import__的形式导入模块并通过 hasattr和getattr 检查并获取函数返回值。

二、面向对象

面向对象简称OOP,面向对象的程序设计把计算机程序视为一组对象的集合,而每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

语法格式见下图:

关键字class 和函数def 是一样的。类名通常是大写开头的单词,定义号类后就可以创建实例如上图的类加()就相当于创建一个类的实例obj

  1. def Bar(self)  其中self 为形式参数
  2. 和实例化对象obj的内存地址相同

类的三大特性:封装、继承、多态

1、封装

面向对象编程的一个重要特点就是数据封装。例如:

class Foo:
    def fetch(self):
        print(self.beckend)  #self 直接在对象里面取值

obj = Foo()
obj.beckend = ‘www.baidu.com‘  #把beckend封装在对象里面
obj.fetch()

class Foo :
        ‘‘‘构造方法‘‘‘
    def __init__(self,bk):
        self.backend = bk  # 把obj对象的参数封装在 init 方法里
    def fetch(self):
        print(self.backend)
    def add(self):
        print(self.backend)
obj = Foo(‘www.xxx.com‘)
obj.fetch()
obj.add()

通过代码我们看到__init__:称之为构造方法,需要注意__init__的第一个参数永远是self,表示的实例本身

封装的意义:当同一类型的方法具有相同的参数时,可以直接封装到对象里减少代码量。

使用场景把类当作模版,创建多个对象并且对象内封装的数据可以不同。

2、继承

当我们定义一个class的时候,可以从某个现有的class继承,新的class称为子类(Subclass),而被继承的class称为基类、父类或超类(Base class、Super class),有几点要注意:

  1. 继承要在子类加上父类的类名
  2. 子类和父类都有的方法,优先找子类的方法
  3. python里面可以继承多个类C#,java 不可以多继承
  4. 如果继承多个类,继承顺序为从左至右

例如下面的例子:

class Animals:
    def chi(self):
        print(self.Name + ‘ 吃‘)
    def he(self):
        print(self.Name + ‘ 喝‘)

class Dog(Animals):
    def __init__(self,name):
        self.Name = name
    def jiao(self):
        print(self.Name + ‘ 叫‘)
xxoo =Dog(‘某某某‘)

xxoo.chi()
xxoo.he()
xxoo.jiao()

class Animals:
    def chi(self):
        print(self.Name +‘ 吃‘)

    def he(self):
        print(self.Name + ‘ 喝‘)

class Uncle:
    def du(self):
        print(self.Name + ‘ 赌‘)

class Dog(Animals,Uncle):
    def __init__(self,name):
        self.Name = name

xxoo = Dog(‘某某某‘)
xxoo.chi()
xxoo.du()

关于继承顺序需要注意例如 E继承(C,D) -->C继承(A)-->D继承(B) 如下图(python3):

class A:
    def f1(self):
        print(‘A‘)
class B:
    def f(self):
        print(‘B‘)
class C(A):
    def f(self):
        print(‘C‘)
class D(B):
    def f1(self):
        print(‘D‘)

class E(C,D):
    def f(self):
        print(‘E‘)
aa = E()
aa.f1()

第二种查找顺序:E继承(C,D)-->C继承(A),D继承(B)-->A和B都继承(Boos) ,查找顺序如下(python3):

class Boos:
    def f1(self):
        print(‘Boos‘)

class A(Boos):
    def f(self):
        print(‘A‘)
class B(Boos):
    def f(self):
        print(‘B‘)
class C(A):
    def f(self):
        print(‘C‘)
class D(B):
    def f1(self):
        print(‘D‘)

class E(C,D):
    def f(self):
        print(‘E‘)

aa = E()
aa.f1()

  下面说下python27的查找顺序是什么那?

未继承object为经典类查找顺序--> 深度优先

3、多态

即多种形态....

补充:

关于继承如何执行父类的构造方法那?有两种方法如下代码:

class Annimal:
    def __init__(self):
        print(‘Annimal的构造方法‘)

        self.ty = ‘动物‘

class Cat(Annimal):
    def __init__(self):
        print(‘Cat的构造方法‘)
        self.n = ‘猫‘
        super(Cat, self).__init__()  #推荐用这种
        # Annimal.__init__(self)        #第二种方式
c = Cat()

查找源码的过程(self.xxxx(),从底层开始找)

三、成员

分别有静态字段、静态方法、类方法、特性、普通字段、普通方法、


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

class Provice:

    #静态字段

    country =‘China‘

    def __init__(self,name):

        #普通字段

        self.name = name

     #普通方法

    def show(self):

        print(‘show‘)

    @staticmethod  #静态方法

    def xo(arg):

        print(‘xo‘)

        print(arg)

    @classmethod  #类方法,必须要有个cls参数:自动传入类名

    def xxoo(cls):

        print(‘xxoo‘,cls)

    def start(self):

        print(‘start‘)

    @property #特性

    def end(self):

        print(‘end‘)

    @end.setter

    def end(self,values):

        print(values)

        self.name = values #也可以更改内存里的值

Provice.country #类访问静态字段

Provice.xo(‘alex‘#类访问静态方法

Provice.xxoo() #访问类方法

#获取特性值

obj = Provice(‘alex‘)

obj.end

#设置特性值

obj1= Provice(‘alex‘)

obj1.end=‘123‘

print(obj1.name)

#普通方法

obj1= Provice(‘alex‘)

obj1.show()

#普通字段

obj1= Provice(‘alex‘)

print(obj1.name)

成员小节:

  1. 自己去访问自己的成员,除了类中的方法
  2. 通过类访问的有:静态字段、静态方法、类方法
  3. 通过对象访问:普通字段、普通方法 、特性

静态字段:存在类中 ,静态字段存在的意:把对象里面重复的数据只在类里保存一份
静态方法 :没有self 可以传参数,调用的时候也需要传入参数 ,存在的意义:不需要创建对象,就可以访问此方法 ,为类而生
类方法:必须要有个cls参数:自动传入类名
特性  对象调用 、不能加参数,执行不用加括号

普通字段,存放在对象中
普通方法  存在的意义:普通方法如果要想被调用就需要创建self ,为对象而生

四、成员修饰符

公有成员:任何地方都能访问
 私有成员:只有在类的内部才能访问,定义方式为命名时,前两个字符为下划线,如 "__test"


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

class Person:

    country = ‘China‘        #静态字段,属于公有成员

    __planet = ‘Earth‘       #静态字段,属于私有成员

    def __init__(self,name):

        print(‘Person build self.name‘)

        self.name = name

         

    def say(self):

        print(‘The planet is %s‘%Person.__planet)    #在类的内部访问私有静态字段

         

p1 = Person(‘Nothing‘)

p1.say()

print(p1.country)            #访问公有静态字段

print(p1.__planet)          #访问私有静态字段

#执行结果:

Person build self.name

The planet is Earth         #在类的内部可以访问

    print(p1.__planet)

China                   #外部可以访问公有静态字段

AttributeError: ‘Person‘ object has no attribute ‘__planet‘    #外部无法访问私有静态字段

小节:私有成员只能在类内部使用,其他的都不能使用包括继承的子类,也不是绝对 也可以通过访问,但是不推荐

对象._类名__字段名

类的特殊成员:


1

2

3

4

5

6

7

8

9

10

__doc__       表示类的描述信息

__module__     表示当前操作的对象在那个模块

__class__      表示当前操作的对象的类是什么

__init__       构造方法,通过类创建对象时,自动触发执行

__call__       对象后面加括号,触发执行。

__dict__       类或对象中的所有成员

__str__       如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

__init__    构造方法,通过类创建对象时,自动触发执行

__setitem__,__getitem__,__delitem__ 用于索引操作,如字典。分别表示获取、设置、删除数据

五、异常处理  

异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行。

一般情况下,在Python无法正常处理程序时就会发生一个异常。

异常是Python对象,表示一个错误。

当Python脚本发生异常时我们需要捕获处理它,否则程序会终止执行。

语法:


1

2

3

4

5

6

7

8

9

10

11

try:

<语句>        #运行别的代码

except <名字>:

<语句>        #如果在try部份引发了‘name‘异常

except <名字>,<数据>:

<语句>        #如果引发了‘name‘异常,获得附加的数据

else:

<语句>        #如果没有异常发生

finally:

        xxxx  

标准的异常有:

+

五、单例模式

  单例模式,也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。

用装饰器方式实现

def wapper(cls):
    instances = {}
    def inner():
        if cls not in instances:
            instances[cls] = cls()
        return cls
    return inner

@wapper
def Foo():
    pass

f1 =Foo()
f2 =Foo()

print(f1 is f2)

静态方法实现:

class ConnectPool:
    __instatnce=None
    @staticmethod
    def get_instance():
        if ConnectPool.__instatnce:
            return ConnectPool.__instatnce
        else:
            ConnectPool.__instatnce = ConnectPool()
            return ConnectPool.__instatnce

obj =ConnectPool.get_instance()
print(obj)
obj1 =ConnectPool.get_instance()
print(obj1)

  

原文地址:https://www.cnblogs.com/lazily/p/9092561.html

时间: 2024-10-29 14:34:50

Python系列之反射、面向对象的相关文章

Python系列6之面向对象

目录 生成器和迭代器 字符串格式化 内置函数vars 反射 面向对象编程 一. 生成器和迭代器  1. 生成器 生成器具有一种生成的能力,它仅仅代表着一种生成的能力,当我们需要使用的时候,才会通过迭代器去生成它.因为他只代表这一种生成的能力,因此,生成器比较节省内存,它一般通过yield来区分生成的位置.通过next来找到下一个位置. # 当直接去执行genetor函数的时候,会先返回一个1,然后就退出了,因为遇到了yield # 当用一个next之后就会执行2. 然后继续退出 # 也就是说yi

Python系列之反射、函数

一.反射 说反射之前先介绍一下__import__方法,这个和import导入模块的另一种方式 1. import commons 2. __import__('commons') 如果是多层导入: 1. from list.text import commons 2. __import__(' list.text.commons',fromlist=True) #如果不加上fromlist=True,只会导入list目录 反射有即想到4个内置函数分别为:getattr.hasattr.seta

Python系列之 - 反射

一.静态方法(staticmethod)和类方法(classmethod) 类方法:有个默认参数cls,并且可以直接用类名去调用,可以与类属性交互(也就是可以使用类属性) 静态方法:让类里的方法直接被类调用,就像正常调用函数一样 类方法和静态方法的相同点:都可以直接被类调用,不需要实例化 类方法和静态方法的不同点: 类方法必须有一个cls参数表示这个类,可以使用类属性 静态方法不需要参数 绑定方法:分为普通方法和类方法 普通方法:默认有一个self对象传进来,并且只能被对象调用-------绑定

Python系列教程大汇总

Python初级教程 Python快速教程 (手册) Python基础01 Hello World! Python基础02 基本数据类型 Python基础03 序列 Python基础04 运算 Python基础05 缩进和选择 Python基础06 循环 Python基础07 函数 Python基础08 面向对象的基本概念 Python基础09 面向对象的进一步拓展 Python基础10 反过头来看看 Python补充01 序列的方法 Python中级教程 Python进阶01 词典 Pytho

Python之路:面向对象及相关

其他相关 一.isinstance(obj, cls) 检查是否obj是否是类 cls 的对象 1 class Foo(object): 2     pass 3   4 obj = Foo() 5   6 isinstance(obj, Foo) 二.issubclass(sub, super) 检查sub类是否是 super 类的派生类 1 class Foo(object): 2     pass 3   4 class Bar(Foo): 5     pass 6   7 issubcl

python第七周-面向对象编程进阶

申明:本文内容主要转自Alex老师的博客,仅供学习记录! 静态方法 只是名义上归类管理,实际上在静态方法里访问不了类实例中的任何属性 通过@staticmethod装饰器即可把其装饰的方法变为一个静态方法,什么是静态方法呢?其实不难理解,普通的方法,可以在实例化后直接调用,并且在方法里可以通过self.调用实例变量或类变量,但静态方法是不可以访问实例变量或类变量的,一个不能访问实例变量和类变量的方法,其实相当于跟类本身已经没什么关系了,它与类唯一的关联就是需要通过类名来调用这个方法 1 clas

【python】对象和面向对象

类的定义 python支持多重继承,在类名后面的小括号中,可以列出多个类名,以逗号分割. __init__方法在类的实例创建后被立即调用,注意与c++中构造函数不一样,因为对象在调用__init__时已经被构造出来,__init__方法不返回值,__init__方法不是必须要定义的. 每个类方法的第一个参数,包括__init__,都是指向类的当前实例的引用.按照习惯这个参数被称为self.在__init__方法中,self指向新创建的对象,在其他的类方法中,它指向方法被调用的类的实例.尽管当定义

python笔记 - day7-1 之面向对象编程

python笔记 - day7-1 之面向对象编程 什么时候用面向对象: 多个函数的参数相同: 当某一些函数具有相同参数时,可以使用面向对象的方式,将参数值一次性的封装到对象,以后去对象中取值即可: sele是什么? self是一个python自动会给传值得参数: 哪个对象执行方法,self就是哪个对象: 构造方法: 类中有一个特殊的方法,__init__,类()自动执行: 面向对象,三大特性: 封装,继承,多态:  

python中的反射

在绝大多数语言中,都有反射机制的存在.从作用上来讲,反射是为了增加程序的动态描述能力.通俗一些,就是可以让用户参与代码执行的决定权.在程序编写的时候,我们会写很多类,类中又有自己的函数,对象等等.这些类和函数都是为了后序代码服务,程序员决定什么时候用到哪一个类,什么时候调用某个函数.但很多时候,我们需要根据用户的需求来决定执行哪一段代码块.用户可能是通过点击,输入数据,或者其他方式发出指令,反射则将用户的指令传递到需要执行的那一段代码块.这个过程是自动执行的,无需人工去核对用户指令是否应该执行那