zoukankan      html  css  js  c++  java
  • 反射

    列表最开始放4个值到第5个值的时候开辟一倍的空间

    1. 反射
      1. __hashattr__
      2. __getattr__
      3. __setattr__
    2. 内置函数
      1. __str__
      2. __repr__

    反射

    what

    使用字符串数据类型的变量名来获取这个变量的值

    why

    三个场景

    input

    文件 从文件中读出字符串,想转换成变量名

    网络 将网络传输的字符串转换成变量的名字

    反射类中的变量
    推荐静态属性,类方法,静态方法

    class Foo:
      Schoo="oldboy"
      Country = "China"
      language = "Chinese"
      @classmethod
      def class_method(cls):
        print("ww")
      @staticmethod
      def static_method():
        print("static")
      def func(self):
        print("")
    inp = inp(">>>")
    # if inp == "School":print(Foo.School) # 条件判断实现
    # if inp == "School":print(Foo.Country)
    # if inp == "School":print(Foo.language)
    print(getattr(Foo,inp)) #反射实现
    "解析getattr方法"
    getattr(变量名:命名空间,字符串:属于一个命名空间内的变量名)
    Foo.School
    getattr(Foo,"School") # Foo.School
    
    "执行类中的方法"
    Foo.class_method()
    print(getattr(Foo,"class_method")())
    getattr(Foo,"static_method")()
    getattr(Foo,"func")() #Foo.func(1) 不推荐调用对象方法. 通过对象调用
    getattr(Foo,"shuangwaiwai") #没有,会报错。
    "避免不报错"
    if hasattr(Foo,"shuangwaiwai"):
      getattr(Foo,"shuangwaiwai")
    

    反射对象中的变量

    getattr(Foo(),"func")()
    

    反射模块中的变量

    import os
    os.rename("path")
    getattr(os,"rename")
    

    反射本文件中的变量

    a = 1
    b = 2
    import sys
    print(sys.modules["__main__"]) ##本文件的命名空间
    print(sys.modules["__main__"],a)
    print(__name__) #内置变量,字符串类型,
    import sys
    print(sys.modules[__name__]) #反射本文件中的变量 固定使用使用这个命名空间。
    class Foo:
        a = "b"
    import sys
    print(getattr(sys.modules[__name__],"Foo").a)
    

    hasattr
    getattr
    setattr

    class Foo:
      pass
    # Foo.School = "oldboy"
    def func():pass
    setattr(Foo,"School","OLDBOY")
    print(Foo.__dict__)
    "往类,对象,空间里添加方法,永远不能变成方法,只是普通函数。
    但没人这么做。"
    setattr(Foo,"func",func)
    
    class Foo:
        a = "b"
    import sys
    print(setattr(sys.modules[__name__].Foo,"bobo",15))
    print(Foo.__dict__)
    

    delattr

    print(Foo.__dict__)
    delattr(Foo)
    

    wehre

    作业

    场景 角色 类 属性 - 方法
    站在每个角色的角度上思考程序执行的流程

    学生选课,需要1. 学生账号,有课程
    管理员 创建学生账号,课程管理员创建。
    应该先站在管理员的角度上来开发。

    登录必须能够自动识别身份,用户名,密码,身份
    角色登录使用反射

    内置方法

    在不是需要程序员定义,本身就存在在类中的方法就是内置方法
    名字:双下方法,魔术方法,内置方法
    __init__
    不需要我们主动调用,而是在实例化的时候内部自动调用的

    所有的双下方法啊,都不需要我们直接去调用。都有另外一种自动触发它的语法

    __str__,__repr__

    class Course:
      def __init__(self.name,period,price,teacher):
        self.name = name
        self.period = period
        self.price = price
        self.teacher = teacher
      def __str__(self):
        return ""%()
    course_list = []
    python = Course("python","6 month",29800,"bass jon")
    linux = Course("linux","5 month",25800,"oldboy")
    course_lst.append(linux)
    for id,course in enumerate(course_lst,1):
      print("" % ())
      print(id,course)
    #学生选课时,要显示所有的课程
    

    str 何时触发

    当你使用%s格式化的时候触发__str__
    当你打印一个对象的时候触发__str__
    str强转数据类型时 触发__str___

    repr

    repr 是str的备胎
    有__str__的时候执行__str__,没有实现执行__repr__
    repr(obj)内置函数对应的结果是__repr__的返回值
    当你使用%r格式化的时候触发__repr__

    
    print(repr(course))
    print("%r"%course) 
    
    # 查找顺序是 子str -> 父 str -> 子repr ->父repr
    class Foo:
      def __str__(self): #必须return 字符串不然会报错。
          return  "Foo str"
      def __repr__(self):
          return "Foo repr"
    class Son(Foo):
      def __str__(self): #必须return 字符串不然会报错。
          return  "Son str"
      def __repr__(self):
          return "Son repr"
    s1 = Son()
    print(s1)  
    

    " 回到行首

    考试题讲解

    def outer():
      name = "alex"
      def inner():
        # name = "wupeiqi"
        print(name)
      print(inner.__closure__)
    outer()
    

    闭包:装饰器,做缓存

    from urllib.request import urlopen
    def get_url(url):
      ret = urlopen(url)
      content = ret.read().decode("ut8")
      def get():
        if content:
          return content
        else:
          return get
    get_url("http://www.douban.com")
    

    查看特性的fget,fset,fdel

    class Person:
        def __init__(self,first_name):
            self._first_name = first_name
        @property
        def lirst_name(self):
            return self._first_name
        @lirst_name.setter
        def lirst_name(self,value):
            if not isinstance(value,str):
                raise TypeError("Expected a string")
            self._first_name = value
        @lirst_name.deleter
        def lirst_name(self):
            raise  AttributeError("Cant delete attribute")
    a = Person("Guido")
    print(Person.lirst_name.fget)
    

    Python代码被集成到一个大型基础平台架构或程序中。
    一个Python类准备加入到一个基于远程过程调用的大型分布式系统中。
    这种情况下,直接使用get/set方法(普通方法调用)而不是property或许会更容易兼容。

    类名调用形成的问题

    
    class Base:
        def __init__(self):
            print("Base:init")
    class A(Base):
        def __init__(self):
            Base.__init__(self)
            print("A.init")
    class B(Base):
        def __init__(self):
            Base.__init__(self)
            print("B.init")
    class C(A,B):
        def __init__(self):
            A.__init__(self)
            B.__init__(self)
            print("C.init")
    c= C()
    
    class Base:
        def __init__(self):
            print("Base:init")
    class A(Base):
        def __init__(self):
            super().__init__()
            print("A.init")
    class B(Base):
        def __init__(self):
            super().__init__()
            print("B.init")
    class C(A,B):
        def __init__(self):
            super().__init__()
            print("C.init")
    c= C()
    
    class Base:
        def __init__(self):
            print("Base:init")
    class A(Base):
        def __init__(self):
            super().__init__()
            print("A.init")
    class B(Base):
        def __init__(self):
            super().__init__()
            print("B.init")
    class C(A,B):
        def __init__(self):
            A.__init__(self)
            B.__init__(self)
            print("C.init")
    c= C()
    

    只重定义父类某一个特性方法

    class Person:
        def __init__(self,name):
            self._name = name
        @property
        def name(self):
            return self._name
        @name.setter
        def name(self,value):
            if not isinstance(value,str):
                raise TypeError("Expected a string")
            self._name = value
        @name.deleter
        def name(self):
            raise AttributeError("cant delete")
    class SubPerson(Person):
        @Person.name.getter
        def name(self):
            print("get name")
            return super().name
    
    

    类方法的一个主要用途就是定义多个构造器

    import builtins
    vars(builtins)
    

    三元运算是两种结果与if elif else是两种操作

    if j.startswith("组长"):
        gno = 1
    else:
        gno += 1
    
        
    True if j.startswith("组长") else False
    

    mkdir day{1..10}

    awk sed grep

    特性是不可被调用的
    特性有文档,并且需要通过类调用特性中的文档

    D.x.fget__doc__
    D.x.fset__doc__
    D.x.fdel__doc__
    
    

    当我们获得类的__dict__时自定义的私有成员已经改变了名称
    所以当我们过滤时,要用单下划线

    class D:
      def __create_students(self):
        pass
    D.__dict__
    ----------
    "输出"
    _Watcher__create_students
    ----------
    

    为什么会出现包?
    因为一个文件内多个类的遍历需要的时间是一个文件一个类时间的n倍

    函数内pass后的东西正常输出

  • 相关阅读:
    Leetcode 1. Two Sum (Python)
    视觉机器学习------KNN学习
    anaconda新建虚拟环境安装各个依赖包
    Matconvnet安装
    argparse模块
    Matconvnet笔记(一)
    Ubuntu14.04下如何安装TensorFlow
    springboot2+freemarker简单使用
    mongodb安装4.0(rpm)
    检测web界面不能访问后重启
  • 原文地址:https://www.cnblogs.com/yonghuierming/p/9579735.html
Copyright © 2011-2022 走看看