• Python说文解字_杂谈05


    1. isinstance和type:

      is和==符号,is指的是内存地址,是不是一个对象,ID知否相同

      集成链

    class A:
        pass
    
    class B(A):
        pass
    
    b = B()
    print(isinstance(b,B))
    print(isinstance(b,A))
    
    print(type(b) is B)
    print(id(type(b)),id(B))
    # 2943616512536 2943616512536

    2. 类变量和对象变量:

      类中的self == 实例,其实就等于a = A()的a,等于传递进去,这就是为什么类中有self的原因。

    class A:
        aa = 1
        def __init__(self,x,y):
            self.x = x
            self.y = y
    
    
    a = A(2,3)
    A.aa = 11
    a.aa = 100
    print(a.x,a.y,a.aa)
    # 2 3 1
    print(A.aa)
    # print(A.x,A.y) # 抛异常
    
    # 2 3 100
    # 11

      记住:查找的顺序是由下而上进行查找

      记住:类变量只能通过类来更改,如果通过实例去更改,只会开辟一块儿新的变量,类的变量其实不能更改,但是看起来是一个变量。类的变量是所有成员共享的。

    3. 类属性和实例属性的查找顺序:

      定义在内部的实例或者方法。

      查找分深度查找和广度查找,其实前面有类名.__init__这样继承父类的方式就是深度查找,我们Py3用的是MRO算法,用的是C3,super()就是一种C3的查找方法。

    class A:
        name = "A"
        def __init__(self):
            self.name = "obj"
    
    a = A()
    print(a.name)
    # 会打印obj回不到name变量

      

    class D:
        pass
    
    class C(D):
        pass
    
    class B(D):
        pass
    
    class A(B,C):
        pass
    
    print(A.__mro__)
    # (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)

      记住:可以用__MRO__查看继承链的关系。

      记住:py2,必须要写object才有object,py3.不用写也会继承object,是一种新式类

    4. 静态方法、类方法、对象方法(实例方法):

    class Date:
        # 构造函数
        def __init__(self,year,month,day):
            self.year = year
            self.month = month
            self.day = day
    
        def tomoroow(self):
            self.day += 1
    
        @staticmethod
        def parse_from_string(date_str):
            year, month, day = tuple(date_str.split("-"))
            return Date(int(year),int(month),int(day))
    
        @staticmethod
        def valid_str(date_str):
            year, month, day = tuple(date_str.split("-"))
            if int(year)>0 and (int(month)>0 and int(month)<12) and (int(day)>0 and int(day)<=31):
                return True
            else:
                return False
    
        @classmethod
        def from_string(cls,date_str):
            year, month, day = tuple(date_str.split("-"))
            return cls(int(year),int(month),int(day))
    
        def __str__(self):
            return "{year}/{month}/{day}".format(year=self.year,month=self.month,day=self.day)
    
    if __name__ == '__main__':
        new_day = Date(2019,6,7)
        new_day.tomoroow()
        print(new_day)
    
        #2019-6-7
        # date_str = "2019-6-7"
        # year,month,day = date_str.split("-")
        # print(year,month,day)
    
        #用staticmethod完成初始化
        date_str = "2019-6-7"
        new_day = Date.parse_from_string(date_str)
        print(new_day)
    
        # 用staticmethod完成初始化
        date_str = "2019-6-7"
        new_day = Date.from_string(date_str)
        print(new_day)
    
        print(Date.valid_str(date_str))

      记住:类中有属性和方法,前面我们说了属性分:类属性,对象属性(实例属性),还有一种静态属性。在方法这个层面也分:类方法、静态方法和对象方法(实例方法)。

      记住:对象方法平时用的很多,记住在类中的self就是用于传回实例的那个标签的。

      记住:静态方法和类方法相同点就是可以直接通过类来进行访问,不用再实例化。 不同点是:如果返回值是类名的话,静态方法每次都要更改return 类名,而类方法不用。

      记住:静态方法@staticmethod,中的是self。类方法@staticclass,中的是cls。这两种其实就是和什么关联。

     5. 数据封装和私有属性:

    class User:
        def __init__(self,birthday):
            self.__birthday = birthday
    
        def get_age(self):
            return 2019 - self.__birthday
    
    class Student(User):
        def __init__(self,birthday):
            self.__birthday = birthday
    
    if __name__ == '__main__':
        user = User(1981)
        print(user.get_age())
        # print(user.__birthday) # 不能访问
        print(dir(user))
        # ['_User__birthday',
        print(user._User__birthday)
        print(user._Student__birthday)

      记住:私有属性在Py中突破的比较简单一些,不用通过反射机制。

      记住:私有属性其实就是在类中创建了一个_类名.__私有属性的变量而已。我们可以通过dir看到这个变量。而且可以直接拿到那个私有属性。

    6. Py的自省:

      通过一定的机制查询到对象的内部结构。

    class Person:
        """
    """
        name = "user"
    
    class Student(Person):
        def __init__(self,school_name):
            self.school_name = school_name
    
    if __name__ == '__main__':
        user = Student("Oxford")
    
        # 通过__dict__查询属性。
        print(user.__dict__)
        # {'school_name': 'Oxford'}
        print(user.name)
        # user
        print(Person.__dict__)
    
        user.__dict__["schoole_addr"] = "北京"
        print(user.__dict__)
        # {'school_name': 'Oxford', 'schoole_addr': '北京'}
    
        print(dir(user))

       记住:查看类中的属性的两个魔法函数是__dict__和dir,其中dict是一种高效的数据存储方式。用dir可以查看全部的。

      记住:__doc__是查看类中的文档注释内容的。

    7. super函数:

      实际上就是调用我们的父类。

    class A:
        def __init__(self):
            print("A")
    
    class B(A):
        def __init__(self):
            print("B")
            # super(B,self).__init__() #这是Py2的用法
            super().__init__() # 这是Py3的用法。
    
    # 既然重写了B的构造函数,为什么还要去调用super
    # super到底执行顺序是什么样的?
    
    if __name__ == '__main__':
        b = B()

      记住:查找顺序就是MRO

      记住:Py2的调用方法和Py3的调用方法不同,但是Py3也可以用Py2的格式。

    8. 类的调用关系:

      mixin模式(属于Python几大设计模式中的一个,后面说)

      minin类功能单一

      不和基类管理啊,可以和任意基类组合,基类可以不和mixin关联就能初始化成功

      在mixin中不要使用super之中用法。

    9. 上下文管理器with和contextlib

    def exe_try():
        try:
            # f_read = open("bobby.txt")
            print("code started")
            # f_read.close()
            raise KeyError
            return 1
        except KeyError as e:
            print("key error")
            return 2
        else:
            print("other error")
            return 3
        finally:
            print("finally")
            return 4
    
    
    if __name__ == '__main__':
        result = exe_try()
        print(result)
        # 如果有finally语句会return 4,如果没有finally的话,执行try和Except语句,返回2

      上下文管理器协议(是协议就要和魔法函数挂钩)

      因此涉及到了__enter__和__exit__

    # 上下文管理器协议
    class Sample:
        def __enter__(self):
            print("enter")
            return self
        def __exit__(self, exc_type, exc_val, exc_tb):
            print("exit")
        def __str__(self):
            return "this is finally?"
        def do_something(self):
            print("do something")
    with Sample() as sample:
        sample.do_something()
        print(sample)

      记住:上下文管理器,其实就是规定类的进和出的关系。比如我们用with open as f:这样的管理方式,就是在open当中规定了__enter__和__exit__两个魔法函数。进出关系,所以不用关闭了。

      记住:__exit__指的是最后的退出,因此里面要打印字符串打印的__str__是在这个之前的。

      import contextlib

    import contextlib
    
    @contextlib.contextmanager
    def file_open(filename):
        print("file open")  # __enter__
        yield {}
        print("file close") # __exit__
    
    
    with file_open("bobby.txt") as f_opened:
        print("file processing")
        
    # file open
    # file processing
    # file close

      记住:上下文管理器函是一个用装饰器的方式生成一个上下文管理器,巧妙的运行了生成器的特性。yield的方式。

      

      

  • 相关阅读:
    最短路最基本算法———Floyd算法
    最短路最基本算法———Floyd算法
    浅谈最基础的三种背包问题
    浅谈最基础的三种背包问题
    Java中的反射机制Reflection
    Linux下抓包命令tcpdump的使用
    SSRF(服务端请求伪造)漏洞
    Cookie、Session和Token认证
    使用BurpSuite抓取HTTPS网站的数据包
    堆、栈和队列的区别
  • 原文地址:https://www.cnblogs.com/noah0532/p/10987522.html
Copyright © 2020-2023  润新知