python全栈开发day24-__new__、__del__、item系列、异常处理

一.昨日内容回顾

  1.反射

    用字符串类型的名字,操作命名空间的变量。

    反射使用场景:明显的简化代码,能拿到的变量名本来就是一个字符串类型的时候,

    用户输入的,文件读入的,网上传输的

  2.__call__

    对象名() 就会调用__call__方法

  3.__len__

  4.__hash__

  5.__eq__

  6.__dict__

    对象名.__dict__:查看对象空间的变量的变量,

    类名.__dict__ 类空间

  7.__slots__

    #__slots__ = ('name','age')

  8.__module__和__class__

  9.isinstance和issubclass

二.今日内容总结

  1.__new__

    #创建一个对象,是一个构造方法,在初始化方法__init__(self,...)执行之前执行。

      单例模式:

    

class A:
    __instance = None
    def __init__(self,name):
        self.name = name

    def __new__(cls, *args, **kwargs):
        if not cls.__instance:
            cls.__instance = object.__new__(cls)
        return cls.__instance


a = A('alex')
b = A('jack')

print(a.name)
print(b.name)
单例模式举例

  2.__del__

    #在一个对象在内存中删除前,执行__del__方法

    # 对比delattr 使用字符类型的变量从命名空间中删除这个变量

    # 对比@property deleter 伪装成属性的方法,要执行删除属性

  #Python解释器

    #能够主动回收不用的变量

    #在程序结束的时候所有的数据都会被清除

  #如果用户主动删除某个变量

    # 那么这个变量将会主动的被删除

  #无论上述哪种方式

    #在删除一个变量之前都会主动的执行析构方法__del__

        应用:对象删除之前回归操作系统资源

    class B:

      def __init__(self,path):

        self.f = open(path)

      def __del__(self):

        self.f.close()

    b = B('userinfl')

  3.__getitem__、__setitem__、__delitem__

    # 有一些内置模块中的内置方法

      #是依赖__getitem__方法的

      #或者说是依赖item['a']这种调用方式的

             #  洗牌,抽牌例子:

      random.choice方法依赖(__len__,__getitem__)

      random.shuffle方法依赖作用对象还有内置方(__len__,__getitem__,__setitem__)

  

import random
from collections import namedtuple
Card = namedtuple('card', ['rank', 'suit'])


class FranchDeck:
    ranks = [i for i in range(2, 11)] + list('JQKA')
    suits = ['红心', '方块', '黑桃', '梅花']

    def __init__(self):
        self.__cards = [Card(rank, suit) for rank in FranchDeck.ranks for suit in FranchDeck.suits]

    def __len__(self):
        return len(self.__cards)

    def __getitem__(self, item):
        return self.__cards[item]

    def __setitem__(self, key, value):
        self.__cards[key] = value

    def __delitem__(self, key):
        del self.__cards[key]


deck = FranchDeck()
print(deck.__dict__)
print(deck[0])
random.shuffle(deck)
print(deck.__dict__)
print(random.choice(deck))
洗牌和抽牌的例子

  4.异常处理

    #try  except

    #try  except  else

    #try  except  else  finally

    #try   finally

    # assert 1=2

    # raise 主动抛出异常

    # 自定义异常类型

  

class WuException(BaseException):
    def __init__(self, name):
        self.__name = name

    def __str__(self):
        return self.__name


try:
    raise WuException('有东西错了试试吧')
except WuException as e:
    print(e)
    
自定义异常类型例子

三.预习与扩展

  1.对元类metaclass的理解:

   1)、我们用class关键字创建的类,都是通过基类type类创建:

      class Foo(object):

        a = 1

                             def func():

          print(6666)

      等同于:type('Foo',(object,),{'a':1,‘func’:func})

                      def func():

        print(6666)

    2) 、 创建类的时候有优先找__metaclass__,自己没有找父类,父类没有找模块,一直找不到就会利用内置type进行类的创建

     class A:

        __metaclass__ = mm

    3)、我们自己定制元类:

     class metaclasstest(type):

        def __new__(cls,name,bases,dict):

          ..........

          return super().__new__(cls,name,bases,dict(可变化))

  2.内置方法的小结:

    

    

class A:
    name = 'jack'

    def __init__(self):
        super().__init__()

    def __getattr__(self, item):
        print('getattr没有该属性%s' % item)

    def __delattr__(self, item):
        del self.__dict__[item]

    def __setattr__(self, key, value):
        self.__dict__[key] = value

    # def __getattribute__(self, item):
    #     print('getattribute %s 不知道没有该属性' % item)


# __getattr__   调用没有属性时触发 a.age
# __setattr__   添加属性时触发  a.age = 1
# __delattr__   删除属性时触发  del a.age
# __getattribute__ 调用时有没有属性时都会触发 a.age

# -----------------------------------------*---------------------------------------
# 当重写__getattribute__时,别的函数不在执行而是执行__getattribute__
a = A()
a.age
a.age = 1
print(a.__dict__)
有坑可以看看

    

原文地址:https://www.cnblogs.com/wuchenggong/p/9116442.html