python -面向对象-设计模式-属性函数

ernestwang 857 0

设计模式

  • 说明:针对特定场景问题的特定解决方案
  • 单例模式:无论创建多少次对象,得到的始终都是同一个
  • 示例:
    class Person:
        def __new__(cls, *args, **kwargs):
            if not hasattr(cls, '_instance'):
                print('执行创建对象操作')
                cls._instance = object.__new__(cls)
            return cls._instance
        
    p1 = Person()
    p2 = Person()
    
    print(id(p1))
    print(id(p2))
    
    # 判断是否是同一对象
    print(p1 is p2)   
    面向对象
  • 说明:将成员方法当做属性一样访问
  • 作用:干预指定属性的操作(获取、设置)
  • 示例:
    class User:
        def __init__(self, username, password):
            self.username = username
            self.password = password
    
        # 获取器:获取指定属性时自动调用
        @property
        def password(self):
            return '你想干嘛'
    
        # 设置器:设置指定属性时自动调用
        @password.setter
        def password(self, password):
            print('设置新密码', password)
            self.__dict__['password'] = 'xxxx' + password + 'yyyy'
           
    u = User('xiaoming', '123456')
    
    print(u.password)
    # u.password = 'abcdef'
    print(u.__dict__)

内存管理

  • 概念:保证无用的对象得到合理及时的释放
  • 引用计数: 当创建一个对象赋值给一个变量时,将引用计数记为1;当多一个变量指向该对象,计数值加1,当少一个变量指向该对象,计数值减1。减到0时释放该对象,顺便调用对象的__del__方法。
  • 说明:引用计数针对的是可变变量及自定义对象,不可变变量的引用计数是没有意义的。
  • 示例:
    a = 100
    b = 100
    
    print(id(a))
    print(id(b))
    
    from sys import getrefcount
    
    # 不可变变量的引用计数没有意义
    print(getrefcount(a))
    
    lt = [1, 2, 3]
    # 多一个变量指向该对象,引用计数加1
    lt2 = lt
    # 该函数本身会对操作对象的引用计数加1
    print(getrefcount(lt))
    
    # 少一个变量指向该对象,引用计数减1
    del lt2
    print(getrefcount(lt))
    
    class Person:
        def __del__(self):
            print('对象即将释放')
     
    p = Person()
    print(getrefcount(p))
    
    del p
    print('OVER')        
  • 函数传参
    def test(n):
        n += 1
    
    num = 100
    
    # test(num)
    # 传递的是值,与num无关
    
    test(100)
    print(num)
    
    def demo(lt):
        lt[0] = 100
        print('in demo func', id(lt))
        
    x = [1, 2, 3]
    print('global', id(x))
    
    # 多一个引用,可以在函数中修改对象
    # 传递的是引用
    demo(x)
    print(x)
  • 深浅拷贝
    lt = [1, 2, 3]
    
    # 此处不是拷贝数据,只是多了一个引用而已
    lt2 = lt
    
    lt2[0] = 100
    print(lt)
    
    import copy
    
    l = [1, 2, [3, 4]]
    # 浅拷贝:拷贝当前对象,其中的数据引用计数加1
    # l2 = l.copy()
    # l2 = copy.copy(l)
    # 深拷贝:拷贝当前对象,里面的元素也进行拷贝
    l2 = copy.deepcopy(l)
    
    print(l is l2)
    l2[0] = 100
    l2[2][0] = 300
    print(l)
    
    class Person:
        # 浅拷贝时自动触发
        def __copy__(self):
            print('执行浅拷贝')
            # 返回值就是浅拷贝的结果
            return 'xxx'
    
        # 深拷贝时自动触发
        def __deepcopy__(self, memodict={}):
            print('执行深拷贝')
            return 'yyy'
        
    p = Person()
    
    # p2 = copy.copy(p)
    p2 = copy.deepcopy(p)
    
    print(p2)
    print(p is p2)

标签: python

发布评论 0条评论)

还木有评论哦,快来抢沙发吧~

复制成功
微信号: irenyuwang
关注微信公众号,站长免费提供流量增长方案。
我知道了