zoukankan      html  css  js  c++  java
  • 元类,__call__方法和单例模式

    在python中一切皆对象的概念。

    举一个例子:

    class Chinese:
        country=“china”
        def __init__(self, name,age,sex):
            self.name=name
            self.age=age
            self.sex=sex
        def change(self):
            print('%s speak Chinese '%self.name)
    #一切皆对象的原则。 那么这个类Chinese也是对象,那么他也有自己的类。那么他的类就是type

    元类:类的类就是元类。

    我们用class定义类的使用来生产我们自己的对象的

    内置元类type是用来专门产生class定义的类的

    但是如何产生的呢?

    用内置的元类type,来实例化得到我们的类

    class_name=("Chinese")
    class_bases=(object,)#元组
    class_boby='''
    country=“china”
    def __init__(self, name,age,sex):
         self.name=name
         self.age=age
         self.sex=sex
     def change(self):
         print('%s speak Chinese '%self.name)
     '''#类体代码  type()#类名字 基类 和名称空间
    class_dic={}
    exec(class_boby,{},class_dic)
    print(class_dic)#产生了类的名称空间
    #类的三大要素凑齐了
    print(class_name,class_bases,class_dic)

    #实例化了
    Chinese=type(class_name,class_bases,class_dic)
    #print(Chinese)
    p=Chinese('egon',18,'male')
    print(p.name,p.age,p.sex)


    我们为毛要用这种方法来自定义类呢?

    是因为这样我们就了解了,类的底层原理,这样就可以控制类的定了

    ##储备知识__call__方法

    class Foo:
        def __init__(self):#定义的时候自动触发
            pass
        def __str__(self):#在打印的时候自动触发
            pass
        def __del__(self):#在删除的时候自动触发
            pass
        def __call__(self,*args,**kwargs):#在调用的时候自动触发
            print(”__call__“)
    obj=Foo()
    #怎么调用?
    obj(1,2,3,x=1,y=2,z=3)

    3、自定义元类:

    class Mymeta(type):
    # # 来控制类Foo的创建
    # def __init__(self,class_name,class_bases,class_dic): #self=Foo
    # # print(class_name)
    # # print(class_bases)
    # # print(class_dic)
    # if not class_name.istitle():
    # raise TypeError('类名的首字母必须大写傻叉')
    #
    # if not class_dic.get('__doc__'):
    # raise TypeError('类中必须写好文档注释,大傻叉')
    #
    # super(Mymeta,self).__init__(class_name,class_bases,class_dic)
    #
    # # 控制类Foo的调用过程,即控制实例化Foo的过程
    # def __call__(self, *args, **kwargs): #self=Foo,args=(1111,) kwargs={}
    # # print(self)
    # # print(args)
    # # print(kwargs)
    #
    # #1 造一个空对象obj
    # obj=object.__new__(self)
    #
    # #2、调用Foo.__init__,将obj连同调用Foo括号内的参数一同传给__init__
    # self.__init__(obj,*args,**kwargs)
    #
    # return obj
    #
    #
    #
    # #Foo=Mymeta('Foo',(object,),class_dic)
    # class Foo(object,metaclass=Mymeta):
    # """
    # 文档注释
    # """
    # x=1
    # def __init__(self,y):
    # self.Y=y
    #
    # def f1(self):
    # print('from f1')
    #
    #
    # obj=Foo(1111) #Foo.__call__()
    #
    # # print(obj)
    # # print(obj.y)
    # # print(obj.f1)
    # # print(obj.x)
    
     
    
     
    
    # 单例模式
    import settings
    
    class MySQL:
    __instance=None  #(确保实例化为空)
    def __init__(self,ip,port):
    self.ip=ip
    self.port=port
    
    @classmethod
    def singleton(cls):
    if not cls.__instance:  #(如果没有实例化就执行下面文件)
      obj=cls(settings.IP, settings.PORT)
      cls.__instance=obj
    return cls.__instance
    
    obj1=MySQL('1.1.1.2',3306)
    obj2=MySQL('1.1.1.3',3307)
    obj3=MySQL('1.1.1.4',3308)
    
    # obj4=MySQL(settings.IP,settings.PORT)
    # print(obj4.ip,obj4.port)
    
    obj4=MySQL.singleton()
    obj5=MySQL.singleton()
    obj6=MySQL.singleton()
    
    print(obj4 is obj5 is obj6)
  • 相关阅读:
    2021-深信服-安服实习-面试反省
    cookie越权的一个案例
    图片大小相关参数可控导致ddos的一个案例
    流量代理-reGeorg脚本实现
    端口转发-lcx
    渗透各阶段目标&错误配置&正反向连接&MSF初探
    权限维持-几种常用手段复现
    解决pip安装第三方包编码错误:UnicodeDecodeError: 'ascii' codec can't decode byte....
    黑龙江网络安全技能竞赛awd后门分析复现
    实验吧-PHP大法-eregi()函数
  • 原文地址:https://www.cnblogs.com/wuchenyu/p/8870802.html
Copyright © 2011-2022 走看看