exec内置函数的补充

exec: 是一个python内置函数,可以将字符串的代码添加到名称空间中;
  - 全局名称空间
  - 局部名称空间

  exec(字符串形式的代码, 全局名称空间, 局部名称空间)

# 使用exec, code相当于局部名称空间中的名字
code = '''
global x
x = 100 y = 20
def func():
pass def __init__():
pass
''' # 自定义的全局名称空间
global_dic = {
'x': 10000
} # 自定义的局部名称空间
local_dic = { 'y':300
} # print(global_dic)
#
# print(local_dic) exec(code, global_dic, local_dic)
print(global_dic) # {'x': 100, ...} 此处全局变量1000被code中x=100替换 # print(local_dic)
# {'y': 20, 'func': <function func at 0x00000000003D1E18>, '__init__': <function __init__ at 0x00000000023789D8>}
# 局部空间y=300被code中y=20替换

元类

1.什么是元类?
  - 类的类就是type, 其实type就是元类;

2.元类的作用?

  - 元类可以控制类的创建过程!

3.如何创建元类以及使用?

# 1.一切皆对象
list1 = [] # list1 = list([])
# print(type(list1)) # <class 'list'> # 2.自定一个类
class Chinese(object):
country = 'china'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex p_obj = Chinese('tank', 17, 'male')
# print(type(p_obj)) # <class '__main__.Chinese'>
print(Chinese) # 类本质上也是一个对象,因为在python中 一切皆对象 ;
# print(type(Chinese)) # <class 'type'> 说明Chinese类是有type实例化的对象
# 3.如何产生类的:
# 1) 通过class关键字产生类
# 2) 通过调用type类: type() ---> obj ---> Chinese # what: 指的是类名
# bases: 继承的父类 (object, )
# dict: 类的名称空间 code = '''
country = 'china'
def __init__(self, name, age, sex):
self.name = name
self.age = age
self.sex = sex
'''
# class_attr
class_attr = {}
exec(code, {}, class_attr) # type(类的名字, 类的基类, 类的名称空间) ----> 类 ---> 对象
obj = type('Chinese', (object, ), class_attr) # def __init__(what, bases=None, dict=None)
# print(obj)
Chinese = obj
print(Chinese) # <class '__main__.Chinese'>
chinese_obj = obj('tank',18,'male')
print(chinese_obj.country) # china

1.什么是元类?
类的类就是type, 其实type就是元类;

2.为什么要使用元类???
元类可以控制类的创建过程!

# type是python内置的元类
# 自定义一个元类
class MyMetaClass(type): # 控制类的创建
# 优酷需要用到的部分;
def __init__(self, class_name, class_bases, class_dict): # self, obj
print(type(class_name))
# print(class_name.istitle())
if not class_name.istitle():
raise NameError('类的首字母必须大写!')
if not class_dict.get('__doc__'):
raise TypeError('必须给我写注释!!!') # 必须将类中的类名、类的基类、类的名称空间,一并返回给 type中的__init__
super().__init__(class_name, class_bases, class_dict) # 了解: 元类更深层次的作用
# 控制调用类的行为
# 为什么调用类就一定会产生一个空对象,为什么一定会执行__new__
# 其实就是type内部一定会调用一次__call__,由__call__来帮你调用__new__。
# 元类中的__call__就是创建类的过程!!!
def __call__(self, *args, **kwargs):
print(args) # Foo类括号中的值
# 1.造一个空对象obj
obj = object.__new__(self) # 创造一个空的对象 # self ---> User
print(obj.__dict__, 1111111)
# 2.调用类时,__call__会立马调用User.__init__, 并且将obj连同Foo括号内的参数一同传给__init__
self.__init__(obj, *args, **kwargs)
# return一个真正创建的对象
return obj # obj = MyMetaClass()
# obj() # obj() ----> User(10, 20) ----> user_obj
# 被控制类在定义阶段 类名(metaclass=自定义的元类) ---> 会将当前类的
# 1)类名、2)基类、3)类的名称空间 一并 传给 自定义的元类
# metaclass ---> 自定义的元类 ---> 调用自定义的元类(类名, 基类, 类的名称空间)
# type(类名, 基类, 类的名称空间) class User(object, metaclass=MyMetaClass): # MyMetaClass(User, (object, ), {'x':10}) '''tank是真的很帅啊,真的舍不得你们啊!!!'''
def __init__(self):
pass
x = 10 obj = User()
print(obj)
'''

<class 'str'>
  ()
  {} 11111111
  <__main__.User object at 0x000000000258C4E0>

'''

属性查找顺序

class Mymeta(type):  # 但凡继承了type的类才能称之为自定义的元类,否则就是只是一个普通的类
# n=444
def __call__(self, *args, **kwargs): #self=OldboyTeacher这个类
# 1. 先产生一个空对象
tea_obj = self.__new__(self) # tea_obj是OldboyTeacher这个类的对象
# print(self.__new__ is object.__new__)
# tea_obj=object.__new__(self) # 2. 执行__init__方法,完成对象的初始属性操作
self.__init__(tea_obj, *args, **kwargs)
# 3. 返回初始化好的那个对象
return tea_obj class Bar:
# n = 33
pass class Foo(Bar):
# n = 222
pass class OldboyTeacher(Foo, metaclass=Mymeta): # OldboyTeacher=Mymeta('OldboyTeacher',(object,),{...})
# n = 111
school = 'Oldboy' def __init__(self, name, age, sex):
self.name = name #None.name='egon'
self.age = age
self.sex = sex def score(self):
print('%s is scoring' % self.name) def __new__(cls, *args, **kwargs):
# print('=====>')
return super().__new__(cls) tea1 = OldboyTeacher('egon', 18, 'male')
# print(tea1)
print(tea1.__dict__) # print(OldboyTeacher.n) # print(object.__new__)

图示顺序:

python基础语法20 面向对象5 exec内置函数的补充,元类,属性查找顺序的更多相关文章

  1. Python基础学习参考(三):内置函数

    一:内置函数 在第一篇文章中,我们简单的认识了一下print()函数和input()函数,也就是输入和输出,这些函数我们可以直接的调用,不要自己定义或者引入什么,对吧?想这样的函数就叫做内置函数.这里 ...

  2. python基础-第四篇-4.1内置函数

    lambda表达式 lambda表达式是对简单函数的精简化表达 语法结构:函数名 = lambda:运算表达式 def f1(a): a = a + 1 return a ret = f1(1) pr ...

  3. python基础之递归,匿名,内置函数

    递归函数: 什么是递归函数? 函数递归调用:在调用一个函数的过程中,又直接或间接地调用了该函数本身. 递归必须要有两个明确的阶段: ①递推:一层一层递归调用下去,强调:每进入下一层问题规模减少 ②回溯 ...

  4. 数据库三,exec内置函数

    数据库三,exec内置函数 一.数据库查询与执行顺序 必备知识 查询语句的基本操作 - select - from - where - group by - having - distinct - o ...

  5. 第8.17节 Python __repr__方法和__str__方法、内置函数repr和str的异同点对比剖析

    一. 引言 记得刚开始学习Python学习字符串相关内容的时候,查了很多资料,也做了些测试,对repr和str这两个函数的返回值老猿一直没有真正理解,因为测试发现这两个函数基本上输出时一样的.到现在老 ...

  6. 巨蟒python全栈开发-第14天 内置函数2 递归 二分查找

    一.今日内容总览 1.内置函数补充 repr() 显示出字符串的官方表示形式 chr() arscii码中的字,转换成位置 ord() arscii码中的位置,转换成字2.递归 自己调用自己 两个口: ...

  7. Py修行路 python基础 (十八) 反射 内置attr 包装

    一.isinstance 和 issubclass1.isinstance(obj,cls)检查是否obj是否是类 cls 的对象.2.issubclass(sub, super)检查sub类是否是 ...

  8. Python开发【第五篇】内置函数

    abs() 函数返回数字的绝对值 __author__ = "Tang" a = -30 all() 函数用于判断给定的可迭代参数iterable中的所有元素是否都为True,如果 ...

  9. 记录我的 python 学习历程-Day12 生成器/推导式/内置函数Ⅰ

    一.生成器 初识生成器 生成器的本质就是迭代器,在python社区中,大多数时候都把迭代器和生成器是做同一个概念. 唯一的不同就是: 迭代器都是Python给你提供的已经写好的工具或者通过数据转化得来 ...

随机推荐

  1. Vue+Element UI 实现视频上传

    一.前言 项目中需要提供一个视频介绍,使用户能够快速.方便的了解如何使用产品以及注意事项. 前台使用Vue+Element UI中的el-upload组件实现视频上传及进度条展示,后台提供视频上传AP ...

  2. jdk自带监控程序jvisualvm的使用

    监控小程序的配置 生产环境tomcat的配置 编辑应用所在的tomcat服务器下的bin目录下的catalina.sh文件,修改如下: 配置如下内容: export JAVA_OPTS="- ...

  3. 小小见解之python循环依赖

    a.py from b import b print '---------this is module a.py----------' def a(): print "hello, a&qu ...

  4. mysql float类型详解

    mysql float类型详解float类型长度必须设置3以上 不然会报错 out of range如果设置3 就只是 整数+小数的长度 比方说3.23 3.2等等 3.333就不行了 4位了

  5. 文件安全复制之 FastCopy

    FastCopy是Windows平台上最快的文件拷贝.删除软件.由于其功能强劲,性能优越,一时间便超越相同类型的所有其他软件.由于该软件十分小巧,你甚至可以在安装后,直接将安装目录中的文件复制到任何可 ...

  6. iOS13 新特性简介

    目录 一.Dark Mode 暗黑模式 二.Status Bar更新 三.UIActivityIndicatorView加载视图 四.总结 一.Dark Mode 暗黑模式 1.1 iOS13推出了D ...

  7. dubbo入门学习

    官方网址:http://dubbo.apache.org/zh-cn/index.html 学习可以参考官网中文文档:http://dubbo.apache.org/zh-cn/docs/user/q ...

  8. 使用VisualStudio或VisualStudio Code作为代码比较工具

    最近改了了几个还是用SVN托管的老项目,用的客户端是TortoiseSVN,本身这个工具比较好用,就是那个内置的比较文件差异的Diff工具太简陋了,由于TortoiseSVN支持第三方Diff查看器的 ...

  9. HM NIS Edit制作安装包时检测是否有.net4.6环境,没有的时候自动安装。

    把.net4.6安装包打包进安装程序. 关键脚本如下: 头部引用字符串对比库 !include "WordFunc.nsh" 新建一个Section,.Net4.6的文件版本号是4 ...

  10. APS.NET MVC + EF (06)---模型

    在实际开发中,模型往往被划分为视图模型和业务模型两部分,视图模型靠近视图,业务模型靠近业务,但是在具体编码上,它们之间并不是隔离的. 6.1 视图模型和业务模型 模型大多数时候都是用来传递数据的.然而 ...