'''
# 知识储备exec()
# 参数1:字符串形式的命令
# 参数2:全局作用域(字典形式),如果不指定默认就使用globals()
# 参数3:局部作用域(字典形式),如果不指定默认就使用locals()
'''
# g = {
# 'x': 2,
# 'y': 4
# }
# l = {}
# exec('''
# global x, m
# x = 10
# m = 100
#
# z = 3
# ''', g, l)
# print(g)
# print(l)
'''一切皆对象,元类(产生类的类叫元类,默认用class定义的类,他们的元类是type)'''
# 一切皆对象,对象可以怎么用?
# 1.都可以被引用,x = obj
# 2.都可以当做函数的参数传入
# 3.都可以当作函数的返回值
# 4.都可以当做容器类型的元素,l = [func, time, obj, l] # # 类也是对象,Foo = type(...)
# class Foo:
# pass
# obj = Foo()
# print(type(obj))
# print(type(Foo))
# #产生类的类叫元类,默认用class定义的类,他们的元类是type
'''定义类'''
# 方式一class
# class Chinese:
# country = 'china'
# def __init__(self, name):
# self.name = name
# def talk(self):
# print('%s is talking' % self.name)
# print(Chinese)
# 方式二type
#定义类三要素 类名,类的基类, 类的名称空间
# class_name = 'Chinese'
# class_bases = (object,)
# class_body = '''
# country = 'china'
# def __init__(self, name):
# self.name = name
# def talk(self):
# print('%s is talking' % self.name)
# '''
# class_dic = {}
# exec(class_body, globals(), class_dic)
# # print(class_dic)
#
# Chinese1 = type(class_name, class_bases, class_dic)
# print(Chinese1)
'''自定义元类控制类的创建'''
# class Mymeta(type):
# def __init__(self, class_name, class_bases, class_dic):
# if not class_name.istitle():
# raise TypeError('类名首字母必须大写')
# if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
# raise TypeError('必须有注释,且注释不能为空')
# super(Mymeta, self).__init__(class_name, class_bases, class_dic)
# class Chinese(object, metaclass = Mymeta):
# '''
# 国人
# '''
# country = 'china'
# def __init__(self, name):
# self.name = name
# def talk(self):
# print('%s is talking' % self.name)
# c = Chinese('name')
# # Chinese = type(class_name, class_bases, class_dic)
'''知识储备__call__方法'''
# class Foo:
# def __call__(self, *args, **kwargs):
# print(self)
# print(args)
# print(kwargs)
# obj = Foo()
# obj(1, 2, 3, a=1, b=2, c=3) # 元类内部也应该有一个__call__方法,会在调用Foo时触发执行
'''自定义元类控制类的实例化行为'''
# class Mymeta(type):
# def __init__(self, class_name, class_bases, class_dic):
# if not class_name.istitle():
# raise TypeError('类名首字母必须大写')
# if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
# raise TypeError('必须有注释,且注释不能为空')
# super(Mymeta, self).__init__(class_name, class_bases, class_dic)
# def __call__(self, *args, **kwargs):
# # print(self)
# # print(args)
# # print(kwargs)
# # 第一件事,造一个空对象
# obj = object.__new__(self)
# # 第二件事,初始化
# self.__init__(obj, *args, **kwargs)
# # 第三件事,返回obj
# return obj
# class Chinese(object, metaclass = Mymeta):
# '''
# 国人
# '''
# country = 'china'
# def __init__(self, name):
# self.name = name
# def talk(self):
# print('%s is talking' % self.name)
# obj = Chinese('xander') # Chinese.__call__(Chinese, 'xander')
# print(obj.__dict__)
'''自定义元类控制类的实例化行为的应用'''
# 单例模式 # 实现方式一:
# class MySQL:
# __instance = None
#
# def __init__(self):
# self.host = '127.0.0.1'
# self.port = 3306
# @classmethod
# def singleton(cls):
# if not cls.__instance:
# obj = cls()
# cls.__instance = obj
# return cls.__instance
# # obj1 = MySQL()
# # obj2 = MySQL()
# # print(obj1)
# # print(obj2)
# obj1 = MySQL.singleton()
# obj2 = MySQL.singleton()
# print(obj1 is obj2) # 实现方式二:元类的方式
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dic):
if not class_name.istitle():
raise TypeError('类名首字母必须大写')
if '__doc__' not in class_dic or not class_dic['__doc__'].strip():
raise TypeError('必须有注释,且注释不能为空')
super(Mymeta, self).__init__(class_name, class_bases, class_dic)
self.__instance = None
def __call__(self, *args, **kwargs):
if not self.__instance:
obj = object.__new__(self)
self.__init__(obj)
self.__instance = obj
return self.__instance
class Mysql(object, metaclass=Mymeta):
'''单例模式'''
def __init__(self):
self.host = '127.0.0.1'
self.port = 3306
@classmethod
def singleton(cls):
if not cls.__instance:
obj = cls()
cls.__instance = obj
return cls.__instance
obj1 = Mysql()
obj2 = Mysql()
print(obj1 is obj2)

练习

# 练习一:在元类中控制把自定义类的数据属性都变成大写
class Mymate(type):
def __new__(cls, name, args, kwargs):
obj = {}
print(name)
print(args)
print(kwargs)
for a, b in kwargs.items():
if not a.startswith('__'):
obj[a.upper()] = b
else:
obj[a] = b
return type.__new__(cls, name, args, obj)
class Chinese(object, metaclass=Mymate):
country = 'chinese'
def talk(self):
print('is talking')
print(Chinese.__dict__) # 练习二:在元类中控制自定义的类无需init方法
# 1.元类帮其完成创建对象,以及初始化操作;
# 2.要求实例化时传参必须为关键字形式,否则抛出异常TypeError: must use keyword argument
# 3.key作为用户自定义类产生对象的属性,且所有属性变成大写
class Mymate(type):
def __call__(self, *args, **kwargs):
if args:
raise TypeError(':must use keyword argument')
obj = object.__new__(self) #创建对象,self为类Chinese for k, v in kwargs.items():
obj.__dict__[k.upper()] = v
return obj class Chinese(object, metaclass=Mymate):
country = 'chinese'
def talk(self):
print('is talking')
p = Chinese(name='egon', age=18, sex='male')
print(p.__dict__)

python 元类以及练习的更多相关文章

  1. python元类:type和metaclass

    python元类:type和metaclass python中一切皆对象,所以类本身也是对象.类有创建对象的能力,那谁来创建类的呢?答案是type. 1.用tpye函数创建一个类 class A(ob ...

  2. Python 元类 - Metaclasses

    Python 元类 - Metaclasses 默认情况下儿, classes 是有 type() 构造的. 类的结构体在一个新的 namespace 被执行, 类的名字 class name 绑定( ...

  3. Python进阶丨如何创建你的第一个Python元类?

    摘要:通过本文,将深入讨论Python元类,其属性,如何以及何时在Python中使用元类. Python元类设置类的行为和规则.元类有助于修改类的实例,并且相当复杂,是Python编程的高级功能之一. ...

  4. python 元类

    转载自  http://blog.jobbole.com/21351/ 类也是对象 在理解元类之前,你需要先掌握Python中的类.Python中类的概念借鉴于Smalltalk,这显得有些奇特.在大 ...

  5. [python]python元类

    这两天在看Django框架,里面的filter实现原理搞不明白,最后发现跟python的元类有关系. 原文:http://stackoverflow.com/questions/100003/what ...

  6. Python元类实践--自己定义一个和collections中一样的namedtuple

    大家可能很熟悉在collections模块中有一个很好用的扩展数据类型-namedtuple. 如果你还不知道这个类型,那么请翻看标准手册. 我利用元类轻松定义一个namedtuple. 先把代码贴上 ...

  7. python元类分析

    刚開始接触到Python新式类中的元类的概念的时候非常是纠结了下..不知道这是个啥东西... 用下面几个定义来说明吧: (1)Python中,类也是对象..仅仅只是这样的对象比較的特殊,他用于创建别的 ...

  8. python元类理解2

    恩,对元类理解又有新的收获,其实类似于装饰器,只不过装饰器是修饰函数,元类用来定制一个类. 代码如下,这是一个使用了函数做元类传递给类: input: def upper_attr(class_nam ...

  9. 3.python元类编程

     1.1.propety动态属性 在面向对象编程中,我们一般把名词性的东西映射成属性,动词性的东西映射成方法.在python中他们对应的分别是属性self.xxx和类方法.但有时我们需要的属性需要根据 ...

  10. Python—元类

    什么是元类? 元类是类的类,是类的模板 元类是用来控制如何创建类的,正如类是创建对象的模板一样,而元类的主要目的是为了控制类的创建行为 元类的实例化的结果为我们用class定义的类,正如类的实例为对象 ...

随机推荐

  1. Photo3

    Story: 这是一个简朴的家,有用旧了的风扇,木制的桌子,桌子上放了未完成的功课,还有一只正在睡觉的猫.阳光从窗户照进来,微风轻轻的吹着.想象你是坐在窗边吹风的小女孩,你的眼睛正眺望着不远处的风景, ...

  2. Yii2.0 多语言设置(高级版配置方法) - 新的方法

    1.设置默认语言:在mail.php配置文件加上:'language'=>'zh_CN'; 2.多语言切换 (我这边是在site控制器里面操作的所以用的'/site/language') htm ...

  3. ngix 创建新的网站

    1. 进入ngix 的目录的conf 目录 的 vhosts 2. 复制一份新的v2.edc.com.conf 3. server_name : v2.edc.com root :  /ali/... ...

  4. setoolkit基础

    1.社会工程学攻击 2.快速追踪测试 3.第三方模块 4.升级软件 5.升级配置 6.帮助 99.退出 1.鱼叉式网络钓鱼攻击 2.网页攻击 3.传染媒介式(俗称木马) 4.建立payloaad和li ...

  5. 开源SLAM

    GitHub 上优秀的开源SLAM repo (更新中):https://www.jianshu.com/p/464ca0d0c254 当前的开源SLAM方案:https://www.cnblogs. ...

  6. WCF服务编程 读书笔记——第1章 WCF基础(2)

    续:第1章 WCF基础(1) 元数据交换 服务有两种方案可以发布自己的元数据.一种是基于HTTP-GET协议提供元数据, 另一种则是后面将要讨论的使用专门的终结点的方式.WCF能够为服务自动提供基于H ...

  7. 编写高质量代码改善C#程序的157个建议——建议116:避免用非对称算法加密文件

    建议116:避免用非对称算法加密文件 MD5值或者说HASH值是一种不可逆的算法.如果需要从密文还原成明文,那么就需要对称和非对称这两类可逆算法了. 对称算法示意图: 在对称算法中,首先需要发送方和接 ...

  8. MFC中按钮控件的用法笔记(转)

    VC学习笔记1:按钮的使能与禁止 用ClassWizard的Member Variables为按钮定义变量,如:m_Button1:则m_Button1.EnableWindow(true); 使按钮 ...

  9. Linq的使用场景简介和认识

    一:C#的一个分支Linq 二:学Linq需要有一些基础知识 1. var 隐式类型 2. 匿名类型/匿名方法 3. 自动属性 4. 委托/泛型的委托 5. lambda 6. 扩展方法 7. 对象初 ...

  10. Linux Guard Service - 前台进程和后台进程切换

    把一个正在执行的程序放入后台 [root@localhost 01]# Ctrl+Z 此使程序被移动到后台,但不能继续输出(处于暂停态) [root@localhost 01]# ./test1-1 ...