一、eval、exec内置函数

1、eval函数

eval内置函数的使用场景:
①执行字符串会得到相应的执行结果
②一般用于类型转换得到dict、list、tuple等

2、exec函数

exec应用场景 用来辅助了解元类的概念

①执行字符串没有执行结果(没有返回值)

②将执行的字符串中产生的名字形成对应的局部名称空间

解析exec函数
exec函数帮我们运行字符串中的代码,把字符串中产生的名字放到名称空间里 自己定义全局作用域中的名字和字典,自己定义局部作用域的名字和字典
将所要执行的代码放到字符串中,在字符串中写好操作全局作用域的和局部作用域的 字符串内放一堆代码,exec来运行字符串中的代码的时候产生的名字都会放到名称空间里,
放到自己定义的全局或者是局部的名称空间里,如果声明是global,就会放到global的字典里
exec(字符串,global_dic, local_dic)
code = """
global x
x=0
y=2
"""
global_dic = {'x': 100000}
local_dic = {}
exec(code, global_dic, local_dic)
print(global_dic)
print(local_dic) # {'y': 2} code = """
x=1
y=2
def f1(self,a,b):
pass
"""
local_dic = {}
exec(code, {}, local_dic)
print(local_dic) # {'x': 1, 'y': 2, 'f1': <function f1 at 0x00000000027A8C80>}

二、类的名称空间的控制

class A:
pass print(A.__dict__) a = A()
print(a, type(a)) # <__main__.A object at 0x00000000021E7400> <class '__main__.A'> print(A, type(A)) # <class '__main__.A'> <class 'type'> print(type)    # <class 'type'>
print(type(type)) # <class 'type'> python中万物皆对象,所有用来创建对象的类,本身也是对象,类是type类的对象
type类叫做元类,是所有元类的基类
元类:制造类的类 --类的类
控制类的产生
控制类的对象的产生 s = '''
my_a = 10
my_b = 20
def __init__(self):
pass
@classmethod
def print_msg(cls, msg):
print(msg)
'''
dic = {}
exec(s, {}, dic) C = type('C', (object, ), dic)
print(C, type(C), C.__bases__) # <class '__main__.C'> <class 'type'> (<class 'object'>,)
print(C.__dict__)
c1 = C()
print(c1.my_a) #
C.print_msg('') class D:
my_a = 10
my_b = 20 def __init__(self):
pass
@classmethod
def print_msg(cls, msg):
print(msg) c1 = C()
print(c1.my_a) #
C.print_msg('') #

三、元类

1、定义:

python中万物皆对象,所有用来创建对象的类,本身也是对象,类是type类的对象

type类叫做元类,是所有元类的基类

元类:制造类的类 --类的类

控制类的产生

控制类的对象的产生

2、__init__、__call__、__new__的用法

①__init__:实例化的时候会自动触发__init__的执行

②__call__:调用类的时候会自动触发

class Zoo:
def __init__(self):
print('') # 对象实例化时候触发
def __str__(self): # 打印对象的时候产生
return 'abc'
def __del__(self): # 删除对象的时候触发
pass
def __call__(self, *args, **kwargs): # 调用类的时候触发
print('')
obj = Zoo() #
print(obj) # abc
obj() # 2 # 调用对象

③__new__:

class CountError(Exception):
pass class MyMeta(type): # 自定义元类,重写init方法的目的:
# 1.该方法是从type中继承来的,所以参数同type的init
# 2.最终的工作(如果开辟空间,如果操作内存)还是要借助type
# 3.在交给type最终完成工作之前,可以对类的创建加以限制 *****
def __init__(cls, class_name: str, bases, namespace):
print(cls) # <class '__main__.Student'>
print(class_name) # Student
print(bases) # (<class 'object'>,)
print(namespace) # {'__module__': '__main__', '__qualname__': 'Student', '__init__': <function Student.__init__ at 0x0000000001EA89D8>}
# 需求:由给元类控制的类的类名必须首字母大写
if not class_name.istitle():
raise NameError('名字首字母必须大写')
# 需求:定义类是必须明确父类
if len(bases) == 0:
raise CountError('父类必须明确') # super(MyMeta, cls).__init__(class_name, bases, namespace)
super().__init__(class_name, bases, namespace) # 自定义元类,重写call方法的目的:
# 1.被该元类控制的类生成对象,会调用元类的call方法
# 2.在call中的返回值就是创建的对象
# 3.在call中
# 通过object开辟空间产生对象
# 用被控制的类回调到自己的init方法完成名称空间的赋值
# 将修饰好的对象反馈给外界
def __call__(cls, *args, **kwargs):
print('call fn run') # call fn run
obj = object.__new__(cls)
# 需求:所有通过该元类控制的类产生的对象都有meta_name该属性
obj.meta_name = cls.__name__
# obj.name = args[0]
# 调回当前被控制的类自身的init方法,完成名称空间的赋值
cls.__init__(obj, *args, **kwargs)
return obj # Student = MyMeta(class_name, bases, namespace)
class Student(object, metaclass=MyMeta):
def __init__(self, name, age):
print('init fn run') # init fn run
self.name = name
self.age = age
pass # stu = Student() # class Teacher(Student, metaclass=MyMeta):
# pass stu = Student('Bob', 18)
print(stu, stu.name, stu.age) # <__main__.Student object at 0x0000000001EB7FD0> Bob 18
stu = Student('Tom', 20)
print(stu.meta_name) # Student

3、自定义元类控制类的创建

需求:类名的首字母必须大写;类中必须写好文档注释

①需求:类名首字母必须大写
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dic):
if not class_name.istitle():
raise TypeError('类名必须大写')
super().__init__(class_name, class_bases, class_dic) # 重用父类的方法 class Foo(object, metaclass=Mymeta):
pass ②需求: 类中必须有文档注释
class Mymeta(type):
def __init__(self, class_name, class_bases, class_dic):
if not class_dic.get('__doc__'):
raise TypeError('类中必须写好文档注释')
super().__init__(class_name, class_bases, class_dic) class Zoo(metaclass=Mymeta):
"""
文档注释
"""
pass

四、单例

1、定义:一个类只能产生一个实例

2、为什么要有单例:

①该类需要对象的产生

②对象一旦产生,在任何位置再实例化对象,只能得到第一次实例化出来的对象

3、单例实现的四种方法:

①方法1
class Songs():
__instance = None
@classmethod
def getInstance(cls):
# 对象没有创建返回,有直接返回
if cls.__instance == None:
cls.__instance = cls()
return cls.__instance # 约定别用 类名() 来实例化对象,用类方法来获取唯一对象
s1 = Songs()
s2 = Songs() print(s1) # <__main__.Songs object at 0x0000000001E776D8>
print(s2) # <__main__.Songs object at 0x0000000001E77710>
print(s1 is s2) # False s1 = Songs.getInstance()
s2 = Songs.getInstance() print(s1) # <__main__.Songs object at 0x00000000027A76D8>
print(s2) # <__main__.Songs object at 0x00000000027A76D8>
print(s1 is s2) # True ②方法2
class Songs:
__instance = None
def __new__(cls, song_name, *args, **kwargs):
if cls.__instance == None:
cls.__instance = object.__new__(cls)
cls.__instance.song_name = song_name
return cls.__instance def change_song(self, song_name):
self.song_name = song_name s1 = Songs('菊花爆满山')
s2 = Songs('感觉身体被掏空')
print(s1.song_name, s2.song_name) # 菊花爆满山 菊花爆满山
s2.change_song('感觉身体被掏空')
print(s1.song_name, s2.song_name) # 感觉身体被掏空 感觉身体被掏空 ③方法3:采用装饰器
def outer(cls):
_instance = None
def inner(*args, **kwargs):
nonlocal _instance
if _instance == None:
_instance = cls(*args, **kwargs)
return _instance
return inner @outer # Songs = outer(Songs)
class Songs:
pass s1 = Songs()
s2 = Songs()
print(s1) # <__main__.Songs object at 0x0000000001EB7748>
print(s2) # <__main__.Songs object at 0x0000000001EB7748>
print(s1 is s2) # True ④方法4
class SingleMeta(type):
__instance = None
def __call__(cls, *args, **kwargs):
if SingleMeta.__instance == None:
SingleMeta.__instance = object.__new__(cls)
cls.__init__(SingleMeta.__instance, *args, **kwargs)
return SingleMeta.__instance class Songs(metaclass=SingleMeta):
def __init__(self):
pass
pass s1 = Songs()
s2 = Songs()
print(s1) # <__main__.Songs object at 0x0000000001E775C0>
print(s2) # <__main__.Songs object at 0x0000000001E775C0>
print(s1 is s2) # True

day29 二十九、元类、单例的更多相关文章

  1. 29 内置方法 eval | exec 元类 单例

    eval与exec内置方法 将字符串作为执行目标,得到响应结果 eval常用作类型转换:该函数执行完有返回值 exec拥有执行更复杂的字符串:可以形成名称空间 eval内置函数的使用场景:   1.执 ...

  2. Java学习笔记(二十四):单例设计模式singleton

    为什么要使用singleton设计模式? 假设设计了一个操作数组的工具类(Tools),里面有一个锤子的方法(Hammer),如果不使用singleton设计模式,每次想调用Hammer方法都需要ne ...

  3. Bootstrap <基础二十九>面板(Panels)

    Bootstrap 面板(Panels).面板组件用于把 DOM 组件插入到一个盒子中.创建一个基本的面板,只需要向 <div> 元素添加 class .panel 和 class .pa ...

  4. mysql进阶(二十九)常用函数

    mysql进阶(二十九)常用函数 一.数学函数 ABS(x) 返回x的绝对值 BIN(x) 返回x的二进制(OCT返回八进制,HEX返回十六进制) CEILING(x) 返回大于x的最小整数值 EXP ...

  5. 《手把手教你》系列技巧篇(二十九)-java+ selenium自动化测试- Actions的相关操作上篇(详解教程)

    1.简介 有些测试场景或者事件,Selenium根本就没有直接提供方法去操作,而且也不可能把各种测试场景都全面覆盖提供方法去操作.比如:就像鼠标悬停,一般测试场景鼠标悬停分两种常见,一种是鼠标悬停在某 ...

  6. Web 开发人员和设计师必读文章推荐【系列二十九】

    <Web 前端开发精华文章推荐>2014年第8期(总第29期)和大家见面了.梦想天空博客关注 前端开发 技术,分享各类能够提升网站用户体验的优秀 jQuery 插件,展示前沿的 HTML5 ...

  7. WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载]

    原文:WCF技术剖析之二十九:换种不同的方式调用WCF服务[提供源代码下载] 我们有两种典型的WCF调用方式:通过SvcUtil.exe(或者添加Web引用)导入发布的服务元数据生成服务代理相关的代码 ...

  8. JAVA之旅(二十九)——文件递归,File结束练习,Properties,Properties存取配置文件,load,Properties的小练习

    JAVA之旅(二十九)--文件递归,File结束练习,Properties,Properties存取配置文件,load,Properties的小练习 我们继续学习File 一.文件递归 我们可以来实现 ...

  9. FreeSql (二十九)Lambda 表达式

    FreeSql 支持功能丰富的表达式函数解析,方便程序员在不了解数据库函数的情况下编写代码.这是 FreeSql 非常特色的功能之一,深入细化函数解析尽量做到满意,所支持的类型基本都可以使用对应的表达 ...

随机推荐

  1. 2018年7月6日go语言学习

    Go是一门并发支持.垃圾回收的编译型系统编程语言. 特点:类型安全和内存安全 以非常直观和极低的方案实现高并发 高效的垃圾回收机制 快速编译 为多核计算机提供性能提升方案 Utf-8编码支持 Go源码 ...

  2. django上下文处理器的基本使用

    1.定义一个方法 2.在django里面的settings.py里面修改配置文件 3.最后在模板里面调用 操做步骤如下: 这是在settings.py里面配置的文件   在模板里面调用上下文处理器

  3. elk搭建日志系统

    参考:https://www.cnblogs.com/yuhuLin/p/7018858.html 以上这篇文章已经写的很好很全了,之所以再自己写一遍大概就是记录一下,以后可能会有用吧 安装elast ...

  4. Dos.Common

    引言: Dos.Common是一个开发中的常用类库,如HttpHelper.LogHelper.CacheHelper.CookieHelper.MapperHelper等等.与Dos.WeChat. ...

  5. Windows2016的 IIS中配置PHP7运行环境

    Windows2016的 IIS中配置PHP7运行环境 在Windows 的IIS(8.0)中搭建PHP运行环境: 一:安装IIS服务器 .进入控制面板>>程序和功能>>打开或 ...

  6. mysql收集统计信息

    一.手动  执行Analyze table innodb和myisam存储引擎都可以通过执行“Analyze table tablename”来收集表的统计信息,除非执行计划不准确,否则不要轻易执行该 ...

  7. Intsall The Nessus in you kali linux

    1.first you shold download the nessus on the web station the nessus download site url:  https://www. ...

  8. sass创建web项目环境步骤

    1)npm创建web前端项目环境步骤 1.新建文件夹,在该文件下进入cmd控制台2.输入命令 npm init 回车3.name:名字只支持小写,不支持大写,将大写的名字改为小写即可4.version ...

  9. yagmail 实现发邮件

    yagmail 实现发邮件 yagmail 可以更简单的来实现自动发邮件功能. github项目地址: https://github.com/kootenpv/yagmail 安装 pip insta ...

  10. 利用web.py快速搭建网页helloworld

    访问web.py官网 http://webpy.org/ 根据网站步骤,利用 pip install web.py 若没有 PIP 则先安装pip 运行 sudo apt-get install py ...