• Python:反射和面向对象(一)


    • 反射

    在所有语言里面都有这个名词:反射。反射也就是:通过字符串的形式,导入模块。通过字符串的形式,去模块中寻找指定函数,并执行。Python中的反射功能是由以下四个内置函数提供:

    hasattr(模块,"成员"):根据字符串的形式去某个模块中检查是否含有某成员

    getattr(模块,"成员"):根据字符串的形式去某个模块中获取成员

    setattr(模块,"成员"):根据字符串的形式去某个模块中设置成员

    delattr(模块,"成员"):根据字符串的形式去某个模块中删除成员

    正常导入模块:

    首先定义一个模块,模块里面有几个函数:

    然后导入模块,执行函数:

    import commons
    r = commons.f1()
    print(r)
    
    #打印结果:
    f1
    F1

     此时有个需求:根据用户输入的内容,导入模块

    #用户输入什么我们就拿到哪个字符串
    inp = input("请输入模块:")
    print(inp,type(inp))
    
    #打印结果:
    请输入模块:commons
    commons <class 'str'>

     再根据用户输入的内容,导入模块,执行函数:

     之前我们学过__import__(字符串):用于以字符串的形式去某个模块中找函数,so:

    #import commons as CC
    #本质:__import__
    #DD = __import__("commons")
    
    #应用通过字符串形式导入模块:
    
    inp = input("请输入模块:")
    print(inp,type(inp))
    
    r = __import__(inp)
    #模块中寻找函数并且执行函数
    #此时f1()还并不是字符串
    ret = r.f1()
    print(ret)
    
    #打印结果:
    请输入模块:commons
    commons <class 'str'>
    f1
    F1

     现在根据字符串形式去模块中寻找函数并且执行函数:

    inp_name = input("请输入模块:")
    inp_func = input("请输入要执行的函数:")
    #导入输入的模块
    inp = __import__(inp_name)
    #获取模块中的函数名
    target_func = getattr(inp,inp_func)
    #执行函数
    ret = target_func()
    print(ret)
    #打印结果:
    请输入模块:commons
    请输入要执行的函数f1
    f1
    F1
    # 查看是否存在,不存在False,存在True
    r = hasattr(commons,"NAME")
    print(r)
    
    # 设置成员
    r = setattr(commons,"ARG",lambda a: a + 1)
    print(r)
    
    # 删除成员
    delattr(commons,"NAME")
    #查看已删除成员是否还存在
    r = hasattr(commons,"NAME")
    print(r)

    注:

    #设置None:如果找到成员f1,就会执行;如果没有找到,就会报错
    target_func = getattr(commons,"Name",None)
    ret = target_func()
    print(ret)

    扩展两种导入模块的方式:

    a = __import__("模块名")
    
    a = __import__("文件名.文件名.模块名",fromlist=True)

     示例:

    from lib import account
    
    url = input("请输入url:")
    if url.endswith("login"):
        r = account.login()
        print(r)
    elif url.endswith("logout"):
        r = account.logout()
        print(r)
    elif url.endswith("nb"):
        r = account.nb()
        print(r)
    else:
        print("404")
    View Code
    from lib import account
    
    url= input("请输入url")
    inp = url.split("/")[-1]
    if hasattr(account,inp):
        target_func = getattr(account,inp)
        r = target_func()
        print(r)
    else:
        print("404")
    View Code
    #模块名/函数名
    url = input("请输入url:")
    #模块名和函数名的格式
    target_module,target_func = url.split("/")
    #导入用户输入的模块
    m = __import__("lib."+target_module,fromlist=True)
    if hasattr(m,target_func):
        target_func = getattr(m,target_func)
        r = target_func()
        print(r)
    else:
        print("404")
    View Code

    总结:反射是通过字符串的形式去对象(某个模块)中操作其成员。一切事物皆对象!

    • 面向对象基础

     概述:

    C#、Java只能用面向对象编程。Ruby、Python是可以用函数编程和面向对象。

    • 面向过程编程:根据业务逻辑从上到下写代码
    • 函数式编程:讲某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可
    • 面向对象编程:对函数进行分类和封装

    面向过程编程:初学者最容易接受

    while True:
        if cpu利用率 > 90%:
            #发送邮件提醒
            连接邮箱服务器
            发送邮件
            关闭连接
     
        if 硬盘使用空间 > 90%:
            #发送邮件提醒
            连接邮箱服务器
            发送邮件
            关闭连接
     
        if 内存占用 > 80%:
            #发送邮件提醒
            连接邮箱服务器
            发送邮件
            关闭连接
    面向过程编程

    函数式编程:增强代码的重用性和可读性

    def 发送邮件(内容)
        #发送邮件提醒
        连接邮箱服务器
        发送邮件
        关闭连接
     
    while True:
     
        if cpu利用率 > 90%:
            发送邮件('CPU报警')
     
        if 硬盘使用空间 > 90%:
            发送邮件('硬盘报警')
     
        if 内存占用 > 80%:
            发送邮件('内存报警') 
    函数式编程

    面向对象编程:是一种编程方式,需要使用“类”和“对象”来实现,所以,面向对象编程其实就是对“类”和“对象”的使用。

    面向对象不是所有情况都适用

      类就是一个模板,模板里可以包含多个函数,函数里实现一些功能

      对象则是根据模板创建的实例,通过实例对象可以执行类中的函数

    注:

    •  class是关键字,表示类
    • 创建对象,在类名称后加括号即可
    • 类中定义的函数叫做“方法”
    class Foo:
        def Bar(self):
            print("Bar")
        def Hello(self):
            print("Hello")
    
    obj = Foo()
    obj.Bar()
    obj.Hello()

    函数式编程:执行函数

    面向对象编程:创建对象  通过对象执行方法

    面向对象三大特性

    面向对象的三大特性:封装、继承、多态

    • 封装

    封装,将内容封装到某个地方,以后再去调用被封装在某处的内容。所有在使用面向对象的封装特性时,需要:

    使用场景:

    1、当同一类型的方法具有相同参数时,直接封装到对象即可。

    2、把类当做模板,创建多个对象(对象内封装的数据可以不一样)

    第一步:将内容封装到某处

    __init__:构造方法

    class Foo:
    #####称为构造方法,根据类创建对象时自动执行
        def __init__(self,name):
            self.country = "中国"
            self.Name = name
        def eat(self):
            print(self.Name + "eat")
        def sleep(self):
            print(self.Name + "sleep")
    
    #根据类Foo创建对象(或创建一个Foo类的实例)
    #自动执行Foo类的__init__方法
    obj1 = Foo("zou")
    #根据类Foo创建对象(或创建一个Foo类的实例)
    #自动执行Foo类的__init__方法
    obj2 = Foo("zhang")
    
    obj1.eat()
    obj2.sleep()
    #打印结果:
    zoueat
    zhangsleep

    self是一个形式参数,当执行 obj1 = Foo("zou")时,self等于 obj1

                  当执行 obj2 = Foo("zhang")时,self等于 obj2

     所以,内容其实被封装到了对象 obj1 和 obj2 中,每个对象中都有name属性。

    第二步:从某处调用被封装的内容

      调用被封装的内容时,有两种情况:

    1、通过对象直接调用被封装的内容

    class Foo:
        def __init__(self,name,age):
            self.country = "中国"
            self.Name = name
            self.Age = age
        def eat(self):
            print(self.Name + "eat")
        def sleep(self):
            print(self.Name + "sleep")
    
    #根据类Foo创建对象
    #自动执行Foo类的__init__方法
    obj1 = Foo("zou",18)
    
    #直接调用obj1对象的属性
    print(obj1.Name)
    print(obj1.Age)
    
    #根据类Foo创建对象
    #自动执行Foo类的__init__方法
    obj2 = Foo("zhang",19)
    
    #直接调用obj2对象的属性
    print(obj2.Name)
    print(obj2.Age)
    #打印结果:
    zou
    18
    zhang
    19

    2、通过self间接调用被封装的内容

    class Foo:
        def __init__(self,name,age):
            self.Name = name
            self.Age = age
    
        def f(self):
            print(self.Name)
            print(self.Age)
    
    obj1 = Foo("zou",18)
    obj1.f() # Python默认会将obj1传给self参数,即:obj1.f(obj1),所以,此时方法内部的 self = obj1,即:self.name 是 zou ;self.age 是 18
    
    obj2 = Foo("zhang",19)
    obj2.f() # Python默认会将obj2传给self参数,即:obj2.f(obj2),所以,此时方法内部的 self = obj2,即:self.name 是 zhang ;self.age 是 19

     总结:对于面向对象的封装来说,其实就是使用构造方法将内容封装到对象中,然后通过对象直接或者self间接获取被封装的内容。

    练习:在终端输出如下信息 

    小明,10岁,男,上山去砍柴

    小明,10岁,男,开车去东北

    老李,90岁,男,上山去砍柴

    老李,90岁,男,开车去东北 

    def kanchai(name, age, gender):
        print "%s,%s岁,%s,上山去砍柴" %(name, age, gender)
    
    
    def qudongbei(name, age, gender):
        print "%s,%s岁,%s,开车去东北" %(name, age, gender)
    
    
    kanchai('小明', 10, '')
    qudongbei('小明', 10, '')
    
    
    kanchai('老李', 90, '')
    qudongbei('老李', 90, '')
    函数式编程
    class Foo:
        
        def __init__(self, name, age ,gender):
            self.name = name
            self.age = age
            self.gender = gender
    
        def kanchai(self):
            print "%s,%s岁,%s,上山去砍柴" %(self.name, self.age, self.gender)
    
        def qudongbei(self):
            print "%s,%s岁,%s,开车去东北" %(self.name, self.age, self.gender)
    
    
    xiaoming = Foo('小明', 10, '')
    xiaoming.kanchai()
    xiaoming.qudongbei()
    
    laoli = Foo('老李', 90, '')
    laoli.kanchai()
    laoli.qudongbei()
    面向对象编程

    上述对比可以看出,如果使用函数式编程,需要在每次执行函数时传入相同的参数,如果参数多的话,又需要粘贴复制了... 而对于面向对象只需要在创建对象时,将所有需要的参数封装到当前对象中,之后再次使用时,通过self间接去当前对象中取值即可。

    • 继承

     继承:面向对象中的继承和现实生活中的继承相同,即:子可以继承父的内容。

    例如:

    动物共同功能:吃、喝、睡

    猫特有功能:喵喵叫

    狗特有功能:汪汪叫

    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 + "")
    
    class Cat(Animals):
        def __init__(self,name):
            self.Name = name
        def jiao(self):
            print(self.Name + "")
    
    obj1 = Dog("小黑")
    obj1.chi()
    obj1.jiao()
    obj2 = Cat("小花")
    obj2.chi()
    obj2.jiao()
    #打印结果:
    小黑吃
    小黑汪
    小花吃
    小花喵

    所以,对于面向对象的继承来说,就是将多个类共有的方法提取到父类(基类)中,子类(派生类)仅需继承父类(基类)而不必一一实现每个方法。

    注:

    派生类可以继承基类中所有的功能

    派生类和基类某一方法同时存在,优先找派生类

    class Animals:
        def chi(self):
            print(self.Name + "")
        def he(self):
            print(self.Name + "")
        def sleep(self):
            print(self.Name + "")
    class Uncle:
        def play(self):
            print(self.Name + "")
        def sleep(self):
            print("sleep")
    class Dog(Animals,Uncle):
        def __init__(self,name):
            self.Name = name
        def talk(self):
            print(self.Name + "说话")
    
    obj = Dog("小黑")
    obj.chi()
    obj.sleep()
    #打印结果:
    小黑吃
    小黑睡
    
    
    #####################


    class Animals: def chi(self): print(self.Name + "") def he(self): print(self.Name + "") def sleeping(self): print(self.Name + "") class Uncle: def play(self): print(self.Name + "") def sleep(self): print("sleep") class Dog(Animals,Uncle): def __init__(self,name): self.Name = name def talk(self): print(self.Name + "说话") obj = Dog("小黑") obj.chi() obj.sleep() #打印结果: 小黑吃 sleep ########## 查找顺序:Dog-->Animals-->Uncle

    Python的类可以继承多个类,Java和C#中则只能继承一个类

    Python的类如果继承了多个类,那么寻找方法的方式有两种(Python3中)

    第一种:

    class A:
        def f1(self):
            print("A")
    
    
    class B:
        def f1(self):
            print("B")
    
    
    class C(A):
        def f1(self):
            print("C")
    
    
    class D(B):
        def f1(self):
            print("D")
    
    
    class E(C, D):
        def f1(self):
            print("E")
    
    
    obj = E()
    obj.f()
    #查找顺序:E-->C-->A-->D-->B

    顺序见图:

    第二种:

    class All():
        def f(self):
            print("All")
    
    
    class A(All):
        def f1(self):
            print("A")
    
    
    class B(All):
        def f1(self):
            print("B")
    
    
    class C(A):
        def f1(self):
            print("C")
    
    
    class D(B):
        def f1(self):
            print("D")
    
    
    class E(C, D):
        def f1(self):
            print("E")
    
    
    obj = E()
    obj.f()
    
    # 查找顺序:E-C-A-D-B-All

    顺序见图:

    • 多态

     Python不支持多态并且也用不到多态,多态的概念是应用于C#和Java这一类强类型语言中,而Python崇尚“鸭子类型”。

    鸭子类型:

    class F1:
        pass
    
    
    class S1(F1):
    
        def show(self):
            print 'S1.show'
    
    
    class S2(F1):
    
        def show(self):
            print 'S2.show'
    
    def Func(obj):
        print obj.show()
    
    s1_obj = S1()
    Func(s1_obj) 
    
    s2_obj = S2()
    Func(s2_obj) 
  • 相关阅读:
    javascript调用applet
    mysql“Access denied for user 'root'@'localhost'”问题的解决
    VS2010 加载Dll文件
    预处理符号
    什么是lib文件,lib和dll的关系如何[转]
    git常用命令
    VC项目配置基础[转]
    [转]Linux ftp命令的使用方法
    [转]JavaScript创建Applet 标签的属性介绍 以及 Applet调用JavaScript
    When you publish a workflow in Microsoft Dynamics CRM 4.0 after you install Update Rollup 2, you receive Error message
  • 原文地址:https://www.cnblogs.com/0820-zq/p/5548396.html
Copyright © 2020-2023  润新知