python08-反射 & 面向对象(一)

反射

  • 反射:
    1. 通过字符串的形式导入模块
    2. 通过字符串的形式去模块中寻找制定的成员(属性、函数),并使用
# 1.创建index.py主程序
# 2.创建commoms模块提供函数
# 3.引入commons模块调用模块中的函数

# commoms.py
def f1():
    print('F1')
    return 'F1'

# index.py
import commons
if __name__ == '__main__':
    ret = commons.f1()
    print(ret) # F1
  • 上面的函数是正常导入并执行,如果想导入用户输入的模块名,并调用用户输入的函数,则:
# index.py
if __name__ == '__main__':
    module = input('请输入模块名:')
    mod = __import__(module)
    # ret = mod.f1() # 正常调用
    # print(ret) # 正常输出
    attr = input('请输入方法名:')
    meth = getattr(mod,attr)
    ret = meth()
    print(ret)
  • 上面的函数相当于调用了2个函数

    • __import__():通过字符串导入模块对象
    • getattr(module,attr):获取模块里的元素
  • 其实getattr()函数才叫反射,通过字符串的形式在模块中寻找相应的元素,如果元素不存在,则报错.

  • 可以通过给getattr(module,arrtib,def)设置默认值,防止报错

  • 反射函数

    • getattr():获取属性
    • delattr():删除属性
    • hasattr():判断实行是否存在
    • setattr():添加或修改属性
  • python中,一切皆对象,通过反射,根据字符串去对象中(模块,类)获取元素

  • 扩展

    • 通过__import__()导入的模块如果存在的路径为:lib\modules\moudle.py
    • 如果导入的方式为:__import__('lib.modules.moudle'),则导入的为lib文件夹
    • 如果想解决这个问题,导入的方式为:__import__('lib.modules.moudle', fromlist=True)

基于反射模拟web框架路由系统

  • 根据用户发送不同的url,服务器执行不同的操作,返回不同的结果
  • 原始操作:
    1. 截取url最后的字段,如login,logout,pay等
    2. 通过if,elif,else判断字段,然后执行模块里面的方法
  • 优化:
    1. 如果网站很大,有成百上千个方法,都要if,elif,else来判断,则需要写大量的判断代码
    2. 通过反射来获取相应的方法,然后调用,则可以不用修改index.py方法,只需要在模块里面添加响应的方法,让url中的字段去匹配
  • 完善:
    1. 但是如果网站太大了,所有的方法都写在一个模块里面,维护起来会很麻烦,同时反射获取方法需要更长的时间
    2. 通过分模块来管理不同功能的方法,在url中把模块和方法名都加上,切割后通过__import__(path, fromlist = True)来导入模块,通过反射获取方法
# 1.创建主程序index.py
# 2.创建功能模块
# 3.截取url,获取里面的地址参数执行不同的方法

# url = input("请输入url:")
url = 'www.yuhhcompany.com/account/login'
regex = 'www.yuhhcompany.com'
ret = re.match(regex, url)
if ret != None:
    # 匹配成功
    host, module, method = url.split('/')
    mod = __import__(module, fromlist=True)
    if hasattr(mod, method):
        ret = getattr(mod, method)()
  • 所有的web框架:php,c#,java,Django本质都是这个道理

面向对象

  • 编程语言:

    • java、c#只能通过面向对象编程
    • Python可以通过函数式编程,也可以通过面向对象编程
  • Python面向对象:

    • class:创建类关键字
    • 定义的函数,在函数式编程时称函数,面向对象编程称为方法
    • 方法参数self:每个方法都需要加上self参数,值为调用该方法的对象,点用方法时python会自动传入该参数,不需要自己传
    class Cat:
        def fun1(self):
            pass
        def fun2(self):
            pass
    
    cat1 = Cat()
    cat1.fun1()
    cat1.fun2()
    
  • 方法的参数self:

    • self代表调用方法的对象,不需要自己传入,当调用方法时,python自动帮我们传入该self参数
    class Cat:
        def fun1(self):
            print(self)
    cat1 = Cat()
    print(cat1) # <__main__.Cat object at 0x10073fc50>
    cat1.fun1() # <__main__.Cat object at 0x10073fc50>
    
    • 封装:

      • 如果一个类中多个方法需要用到同一个参数,每次都穿的话,太麻烦
      class Cat:
          def fun1(self, name, age):
              print(name, age)
          def fun2(self, name, age):
              print(name, age)
          def fun3(self, name, age):
              print(name, age)
      
      cat1 = Cat()
      cat1.fun1('yhh', 23)
      cat1.fun2('yhh', 23)
      cat1.fun3('yhh', 23)
      
      • 可以将重复的变量作为对象的属性:
        • 把参数赋值给对象,在方法中调用--封装
      class Cat:
          def fun1(self):
              print(self.name, self.age)
          def fun2(self):
              print(self.name, self.age)
          def fun3(self):
              print(self.name, self.age)
      
      cat1 = Cat()
      cat1.name = 'yhh'
      cat1.age = 23
      cat1.fun1()
      cat1.fun2()
      cat1.fun3()
      
      • 封装使用场景:

        • 连接操作数据库,对数据库的操作(curd)都需要用到ip,port,user,password,content等,如果每个方法都传ip,port,user,passowrd,这样方法的参数重复且调用的时候很麻烦,如果把它们都封装到对象里,直接在对象里调用,这样重复的参数只需要穿一遍即可.
      • 封装步骤

        • 上面的封装过程不够好,因为如果别人看你的代码,别人不一定知道调用方法前需要封装数据,可以优化为:
        • 创建对象时会调用构造方法__init__(),对象销毁的时候会调用__del__()方法(析构方法)
      class Cat:
          def __init__(self, name, age):
              self.name = name
              self.age = age
          def fun1(self):
              print(self.name, self.age)
          def fun2(self):
              print(self.name, self.age)
          def fun3(self):
              print(self.name, self.age)
      
    • 对象序列化

      • 在python中,对象可以通过pickle序列化,然后在本地持久化,可以用来存档
      • 不能用json,因为json只能转成python的基本类型,自定义类不属于基本类型
      import pickle
      
      # 存档
      with open('object.pickle', mode='wb') as file:
          pickle.dump(cat1,file)
      
      # 读档
      with open('object.pickle', mode='rb') as file:
          cat1 = pickle.load(file)
          cat1.fun1() # YHH 23
      
    • 继承

      • python中继承是需要在子类的类名后跟上:(父类类名)
      • 父类--子类
      • 基类--派生类
      • 派生类和父类有相同的方法时,以派生类为主
      class Father:
          def fun1(self):
              print('Father')
      
      class Son(Father):
          def fun2(self):
              print('Son')
      
      son = Son()
      son.fun1()  # Father
      son.fun2()  # Son
      
    • 多继承

      • java、c#只支持单继承
      • python可以多继承
      • 如果A继承B和C,B和C都有相同的方法,则以继承时写在左边的为主,如果A也有这个方法,则以A为主
    • 多继承面试题:

    在pytho3.5中:
    # 如果继承关系
    class E(C,D):
        pass
    # A --> C --> E
    # B --> D --> E
    # E继承CD,C继承A,D即成B
    # 则调用的顺序为:E --> C --> A --> D --> B(顶层没有同一个基类)
    
    # 如果A和B同时又继承BASE基类,则调用顺序为:
    E --> C --> A --> D --> B --> BASE(顶层有同一个基类)
    python2.7不一样
    
    • 多态

      • python本身语言特性就支持多态,像java,c#等因为是强类型语言,比较复杂
      lass Cat():
          def fun1(self):
              print('fun1')
      
      class Dog():
          def fun1(self):
              print('fun1')
      
      def function(animal):
          animal.fun1()
      
      function(Cat())
      function(Dog())
      
      • 其他语言有重载,python不支持
    • 接口

      • python语言没有接口一说
      • 接口类型:
        • 代码级别:interface
        • 业务级别:访问后台的地址
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,590评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 86,808评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 151,151评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,779评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,773评论 5 367
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,656评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,022评论 3 398
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,678评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 41,038评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,659评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,756评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,411评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,005评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,973评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,203评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,053评论 2 350
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,495评论 2 343

推荐阅读更多精彩内容

  • 面向对象 回顾:反射:以字符串的形式去某个对象(模块,类,对象)操作它的成员(python中,一切皆对象)# 从模...
    AndroidCat阅读 243评论 0 0
  • mytest
    via2016阅读 150评论 0 0
  • 我最喜欢的作家是李欣頻,作品叫做「為何心想事不成」。 這本書的的出版是針對「秘密」一書中的內容提供更完整的解釋,因...
    李東東阅读 230评论 4 5
  • 今晚睡的最晚一次,明天就是跨年了,后天就是2017年,希望在新的一年里工作顺利身体健康万事如意,开心快乐每一天。
    志梅阅读 184评论 0 0
  • 一、每日精进 这一项目因为已进入习惯轨道,每天按时按量地做,条件反射一般,毫不懈怠。已经无须每周再一一详述,除非有...
    樱桃庄园阅读 109评论 0 0