__call__方法:

对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

 class Foo:

     def __init__(self):
pass def __call__(self, *args, **kwargs): # 在类中,使用__call__方法,表示实例化的对象可以被调用,也可以传参数进来.
print(args)
print(kwargs) obj = Foo() #obj是由Foo类实例化得来的.那么Foo也是可以被调用的.那么Foo的类的内部也应该有一个__call__的方法.
那么Foo的类是元类type,那么type内部肯定也有一个__call__方法 #Foo是由元类实例化得来的,所以元类内部也有一个__call__方法,会在调用Foo的时候触发执行
#Foo(1,2,3)等价于 Foo__call__(Foo,1,2,3)
obj(1,2,3,x=99,y=100) # 传参到__call__方法中,相当于obj.__call__(obj, 1,2,3,x=99,y=100)
打印输出: (1, 2, 3) {'x': 99, 'y': 100}

自定义元类控制类的实例化行为:

 class Mymeta(type):  # 继承默认元类的一堆属性
def __init__(self,class_name, class_body, class_dic):
if not class_name.istitle():
raise TypeError("类名首字母必须大写!") if "__doc__" not in class_dic or not class_dic["__doc__"].strip():
raise TypeError("必须有注释,且注释不能为空!") super().__init__(class_name, class_body, class_dic) def __call__(self, *args, **kwargs):#Chinese.__call__(Chinese,"jack",18)
# print("__call__ in Mymeta")
print(self) # Chinese
print(args) # "jack",18
print(kwargs) #{}
#实际上是在__call__做了3件事
#1.创建一个空对象
obj = object.__new__(self) # self =Chinese
#2.初始化对象
self.__init__(obj, *args, **kwargs)
#3.返回对象
return obj class Chinese(object, metaclass=Mymeta):
"""
休息休息
"""
def __init__(self, name, age):
self.name = name
self.age = age def tell(self):
print("name:%s,age:%s" % (self.name, self.age)) obj1 = Chinese("jack",18) # Chinese.__call__(Chinese,"jack",18) 相当于调用mymeta下的__call__方法.

单例模式:

 # 单例模式

 class MySql:
__instance =None
def __init__(self):
self.host = "127.0.0.1"
self.port = "" @classmethod
def singeton(cls):
if not cls.__instance : # 检测如果__instance没有值.为None!如果一个对象中的元素是None,not 对象,则返回False
# print("s",cls.__instance)
obj =cls() # 就实例化一个对象
cls.__instance =obj # 把实例化对象的值赋给cls__instance
return cls.__instance sql1 = MySql.singeton()
sql2 = MySql.singeton()
print(sql1 is sql2)
print(id(sql1))
print(id(sql2))
"""
# 由于sql1和sql2都是由MySql实例化得来的,而且它们的参数都是一样的.这样实例化对象,太浪费内存空间了.
我们之前学过a = 1, b =a
其实a,b都指向了1的内存地址.那么我们在实例化相同参数的对象时,也可以使用这种方法.

Day 5-8 自定义元类控制类的实例化行为的更多相关文章

  1. python 通过元类控制类的创建

    一.python中如何创建类? 1. 直接定义类 class A: a = 'a' 2. 通过type对象创建 在python中一切都是对象 在上面这张图中,A是我们平常在python中写的类,它可以 ...

  2. Python 自定义元类的两种写法

    有关元类是什么大家自己搜索了解,我这里写一下实现元类的两种写法 # 自定义元类 #继承type class LowercaseMeta(type): ''' 修改类的属性名称为小写的元类 ''' # ...

  3. 关于MapReduce中自定义带比较key类、比较器类(二)——初学者从源码查看其原理

    Job类 /**   * Define the comparator that controls    * how the keys are sorted before they   * are pa ...

  4. 自定义标签(JspFragment类、invoke方法、开发带属性的标签)

    自定义标签(JspFragment类.invoke方法.开发带属性的标签) 一.JspFragment类 javax.servlet.jsp.tagext.JspFragment类是在JSP2.0中定 ...

  5. .net之工作流工程展示及代码分享(四)主控制类

    现在应该讲主控制类了,为了不把系统弄得太复杂,所以就用一个类作为主要控制类(服务类),作为前端.后端.业务逻辑的控制类. WorkflowService类的类图如下: 该类的构造函数: public ...

  6. PHP-权限控制类

    http://blog.csdn.net/painsonline/article/details/7183679 <?php /** * 权限控制类 */ class include_purvi ...

  7. Spring自定义一个拦截器类SomeInterceptor,实现HandlerInterceptor接口及其方法的实例

    利用Spring的拦截器可以在处理器Controller方法执行前和后增加逻辑代码,了解拦截器中preHandle.postHandle和afterCompletion方法执行时机. 自定义一个拦截器 ...

  8. Java 扫描实现 Ioc 动态注入,过滤器根据访问url调用自定义注解标记的类及其方法

    扫描实现 Ioc 动态注入 参考: http://www.private-blog.com/2017/11/16/java-%e6%89%ab%e6%8f%8f%e5%ae%9e%e7%8e%b0-i ...

  9. Java高级特性--自定义一个StringBuilder的类

    案例讲解--自定义一个StringBuilder的类 一:案例设计介绍 自义一个M定yStringBuilder来实现StringBuilder的功能 二:案例设计 实现append()方法追加字符串 ...

随机推荐

  1. 设计模式のNullObjectPattern(空对象模式)----行为模式

    一.产生背景 在空对象模式(Null Object Pattern)中,一个空对象取代 NULL 对象实例的检查.Null 对象不是检查空值,而是反应一个不做任何动作的关系.这样的 Null 对象也可 ...

  2. SpringMVC handleMapping映射过程

    初始化IOC容器 Spring初始化的时候会优先初始化自定义的类,下面这个就是 org.springframework.web.servlet.mvc.method.annotation.Reques ...

  3. RocketMQ实现事务消息

    在RocketMQ4.3.0版本后,开放了事务消息这一特性,对于分布式事务而言,最常说的还是二阶段提交协议,那么RocketMQ的事务消息又是怎么一回事呢,这里主要带着以下几个问题来探究一下Rocke ...

  4. multiply对应位置相乘 与 dot矩阵乘

    区别 # -*- coding: utf- -*- import numpy as np a = np.array([[,], [,]]) b= np.arange().reshape((,)) c ...

  5. oldboy-作业01.登录多次进行账号锁定

    """可以支持多个用户登录 (提示,通过列表存多个账户信息)用户3次认证失败后,退出程序,再次启动程序尝试登录时,还是锁定状态(提示:需把用户锁定的状态存到文件里) &q ...

  6. 16 python 初学(生成器)

     列表生成器(列表生成式): 使用此种方式生成的列表会放在内存中占用内存 a = [x*2 for x in range(1, 11)] print(a) # >>> [2, 4, ...

  7. mysql 行转列 列转行

    一.行转列 即将原本同一列下多行的不同内容作为多个字段,输出对应内容. 建表语句 DROP TABLE IF EXISTS tb_score; CREATE TABLE tb_score( id ) ...

  8. 性能调优6:Spool 假脱机调优

    SQL Server的Spool(假脱机)操作符,用于把前一个操作符处理的数据(又称作中间结果集)存储到一个隐藏的临时结构中,以便在执行过程中重用这些数据.这个临时结构都创建在tempdb中,通常的结 ...

  9. zookeeper核心-zab协议-《每日五分钟搞定大数据》

    上篇文章<paxos与一致性>说到zab是在paxos的基础上做了重要的改造,解决了一系列的问题,这一篇我们就来说下这个zab. zab协议的全称是ZooKeeper Atomic Bro ...

  10. (转)C#中的那些全局异常捕获

    C#中的那些全局异常捕获(原文链接:http://www.cnblogs.com/taomylife/p/4528179.html)   1.WPF全局捕获异常       public partia ...