zoukankan      html  css  js  c++  java
  • Python 面向对象进阶(二)

    1. 垃圾回收

    • 小整数对象池
      • Python对小整数的定义是 [-5, 257),这些整数对象是提前建立好的;
      • 在一个Python程序中,所有位于这个范围内的整数,使用的都是同一个对象;
      • 单个字符共用对象,常驻内存;
    • 大整数对象池
      • 每一个大整数,均创建一个新的对象;
    • intern机制
      • 单个单词,不可修改,默认开启intern机制,共用对象,当引用计数为0时,则销毁;
      • 字符串(含有空格),不可修改,没有开启intern机制,不共用对象;
    # 示例:
    a1 = "Helloworld"
    a2 = "HelloWorld"
    a3 = "HelloWorld"
    a4 = "HelloWorld"
    a5 = "HelloWorld"
    a6 = "HelloWorld"
    
    # 说明:
    # intern 机制,内存中只有一个"HelloWorld"所占的空间,靠引用计数去维护何时释放。
    

    1.1 GC 垃圾回收

    • Python 采用的是引用计数机制为主,以分代收集机制为辅的策略;
    • gc 模块常用函数:
      • gc.get_threshold(): 获取gc模块中自动执行垃圾回收的频率;
      • gc.set_threshold(threshold[, threshold1[, threshold2]])设置自动执行垃圾回收的频率;
      • gc.get_count(): 获取当前自动执行垃圾回收的计数器,返回一个长度为3的列表;
      • gc.collect(): 显示执行垃圾回收;
    # 示例:
    # 引用计数缺点:循环引用
    class ClassA():
        def __init__(self):
            print("object born,id:%s" % str(hex(id(self))))
    
    def f2():
        while True():
            c1 = ClassA()
            c2 = ClassA()
            c1.t = c2
            c2.t = c1
            del c1
            del c2
    
    f2()
    

    2. 内建属性和内建函数

    2.1 内建属性

    • 常用属性
      • __init__: 构造初始化函数;
      • __new__: 生成实例所需属性;
      • __class__: 实例所在的类, 实例.__class__
      • __str__: print(类实例)自动调用对象的__str__方法;
      • __int__: int(对象)自动执行对象的__int__方法,并将返回值赋给int对象;
      • __repr__: 实例字符串表示,准确性; 类实例 回车时触发
      • __del__: del 实例时,触发;
      • __dict__: 将对象中封装的所有内容通过字典的形式返回;
      • __doc__: 类文档,子类不继承; help(类或实例)
      • __getattribute__: 属性访问拦截器;
      • __bases__: 类的所有父类构成元素, 类名.__bases__
    # 示例: 属性拦截器
    class Test(object):
        def __init__(self, subject1):
            self.subject1 = subject1
            self.subject2 = 'cpp'
    
        # 属性访问拦截器,打印日志信息
        def __getattribute__(self, obj):
            print("===1>%s" % obj)
            if obj == 'subject1':
                print('log subject1')
                return 'redicrect python'
            else:
                temp = object.__getattribute__(self, obj)
                print("===2>%s" % str(temp))
                return temp
    
        def show(self):
            print("this is a Test")
    
    s = Test("python")
    print(s.subject1)
    print(s.subject2)
    
    s.show()
    # 调用方法步骤:
    # 1. 先使用属性访问拦截器,获取show属性对应的方法;
    # 2. 方法()
    
    
    # 示例二: 属性拦截器注意事项
    class Person(object):
        def __getattribute__(self, obj):
            print("=== test ===")
            if obj.startswith("a"):
                return "haha"
            else:
                return self.test
    
        def test(self):
            print("heihei")
    
    t = Person()
    
    t.a     # 返回 haha
    
    t.b     # 会让程序挂掉
    # 原因: 当 t.b 执行时,会调用Person类中定义的 __getattribute__ 方法, if 条件不满足,所以程序
    # 执行 else 里面的代码, 即 return self.test; 因为 return 需要 self.test 的值返回,那么首先
    # 要先获取 self.test 的值, 因为 self 此时就是对象 t, 所以,self.test = t.test, t.test 此时
    # 要获取t这个对象的 test 属性,那么,就会跳转到 __getattribute__ 方法去执行,即此时产生了递归调用;
    
    
    # 示例三:  __getitem__
    class Foo:
        def __init__(self, name, age):
              self.name = name
               self.age = age
    
        def __getitem__(self, item):
                return item + 10
        
        def __setitem__(self, key, value):
                print(key, value)
        
        def __delitem__(self, key):
                print(key)
    
    li = Foo('zhangsan', 18)
    a = li[8]        # 此处,会自动执行li对象的的 __getitem__ 方法,  8 会当作参数传递给 item
    print(a)
    
    li[100] = 'master'        # 会调用 __setitem__ 方法
    
    del li[666]                # 会调用 __delitem__ 方法
    
    
    # 示例四:   __iter__
    class Foo:
        def __init__(self, name, age):
                self.name = name
                self.age = age
    
        def __iter__(self):
                return iter([11, 22, 33])
    
    li = Foo('alex', 19)
    for i in li:       
         # 1. 执行li对象对应的类 Foo 中的 __iter__ 方法, 并获取其返回值
         # 2. 循环上一步返回的对象
        print(i)
    
    # 备注:
    #       1. 如果类中有 __iter__ 方法, 那么,该类生成的对象为可迭代对象; 
    #        2. 对象.__iter__() 返回值为迭代器;
    
    
    # 示例五: __call__ 方法
    class Foo:
        def __init__:
            pass
    
        def __call__:
            pass
    
    obj = Foo()        # 此处,会自动执行 __init__ 方法
    obj()                 # 此处,会自动执行 __call__ 方法
    

    2.2 内建函数

    • dir(__builtins__): 可以查看Python解释器启动后,默认加载的属性和函数;
    # 示例一: range
    range(stop)
    range(start, stop[, step])
    
    # 备注:
    #   python2中 range 返回列表;
    #   python3中 range 返回一个迭代值;如果想得到列表,可通过 list 函数
    #  pyton3 创建列表的另外一种方法:
    testList = [x*2 for x in range(10)]
    testList
    
    
    # 示例二: map 函数
    # map 函数会根据提供的函数对指定序列做映射
    # map(function, sequence[, sequence, ...]) -> list
    #   function: 函数
    #   sequence: 一个或多个序列,取决于function需要几个参数;
    #   返回值是一个list
    
    # 函数需要一个参数
    map(lambda x: x*x, [1, 2, 3])   # 结果为: [1, 4, 9]
    
    # 函数需要两个参数
    map(lambda x, y: x+y, [1, 2, 3], [4, 5, 6])     # 结果为: [5, 7, 9]
    
    
    # 示例三: filter 函数
    # filter(function or None, sequence) -> list, tuple, or string
    #   function: 接受一个参数,返回布尔值True或False
    #   sequence: 序列可以是 str, tuple, list
    #   filter 函数会对序列参数sequence中的每个元素调用function函数, 最后返回的结果包含调用结果为
    #   True的元素
    
    filter(lambda x: x%2, [1, 2, 3, 4])     # 结果为[1, 3]
    
    
    # 示例四: reduce 函数
    # reduce(function, sequence[, initial])  -> value
    #   function: 该函数有两个参数
    #   sequence: 序列可以是 str, tuple, list
    #   initial: 固定初始值
    #  reduce 函数依次从sequence中取一个元素,和上一次调用function的结果做参数再次调用function。第一次调用
    #  function时,如果提供initial参数,会以sequence中的第一个元素和initial作为参数调用function, 否则会以
    #  序列sequence中的前两个元素做参数调用function。注意,function 函数不能为None
    
    reduce(lambda x, y: x+y, [1, 2, 3, 4])  # 结果为: 10
    
    reduce(lambda x, y: x+y, ['aa', 'bb', 'cc'], 'dd')      # 结果为: ddaabbcc
    
    # 备注: Python3, reduce函数已经从全局名字空间中移除,现在被放置在functools模块里面,
    # 如果需要使用,需要先导入: from functools import reduce
    
    # 示例五: sorted 函数
    # sorted(iterable, cmp=None, key=None, reverse=Fale) -> new sorted list
    
    sroted(['dd','yy','ee','ss','ww'], reverse=1)
    
    

    3. 集合 set

    • 集合与之前列表,元组类似,可以存储多个数据,但是这些数据是不重复的;
    • 集合对象还支持union(联合), intersection(交), difference(差)和sysmmetric_difference(对称差集)等数学运算;
    # 示例:
    a = "abcdef"
    b = set(a)      # 输出: {'a', 'b', 'c', 'd', 'e', 'f'}
    A = "bdfwm"
    B = set(A)
    b&B     # 取交集
    b|B     # 取并集
    b-B     # 取差集
    b^B     # 对称差集(在b或B中,但不会同时出现在二者中)
    

    4. functools

    # Python3
    import functools
    dir(functools)      # 查看所有的工具函数
    
    # 函数一: partial函数(偏函数)
    # 把一个函数的某些参数设置默认值,返回一个新的函数,调用这个新函数会更简单
    
    import functools
    
    def showarg(*args, **kw):
        print(args)
        print(kw)
    
    p1 = functools.partial(showarg, 1,2,3)
    p1()    # 输出: (1, 2, 3) {}
    p1(4, 5, 6)     # 输出: (1, 2, 3, 4, 5, 6)  {}
    p1(a='python', b='java')    #输出: (1, 2, 3) {'b':'java', 'a':'python'}
    
    
    # 函数二: wraps 函数
    # 使用装饰器时,有一些细节需要被注意。例如,被装饰后的函数,其实已经是另外一个函数了(函数属性会发生改变)
    
    def note(func):
        '''note function'''     # 说明文档
        def wrapper():
            '''wrapper function'''
            print('note something')
            return func()
        return wrapper
    
    
    @note
    def test():
        '''test function'''
        print('I am test')
    
    print(help(test))   
    # 输出wrapper的说明文档
    # wrapper()
    #    wrapper function
    
    
    # functools 包提供了 wraps 装饰器来消除这样的副作用
    import functools
    def note(func):
        '''note function'''
        @functools.wraps(func)
        def wrapper():
            '''wrapper function'''
            print('note something')
            return func()
        return wrapper
    
    @note
    def test():
        '''test function'''
        print('I am test')
    
    print(help(test))
    # 输出:
    #   test()
    #       test function
    

    参考资料:

  • 相关阅读:
    【Springboot】Springboot整合Ehcache
    时间戳转化正常的时间格式
    申请抖音企业认证流程
    js与原生进行交互
    vim 高亮
    shell 关于路径查询显示pwd
    shell 关于字符切割 cut
    linux ubuntu 关于vim得一些基本命令
    shell 在终端中打开另一个终端执行命令
    shell 获取时间
  • 原文地址:https://www.cnblogs.com/linkworld/p/8543779.html
Copyright © 2011-2022 走看看