day19-Python运维开发基础(类的魔术方法)
1. __new__魔术方法
# ### __new__ 魔术方法
'''
触发时机:实例化类生成对象的时候触发(触发时机在__init__之前)
功能:控制对象的创建过程
参数:至少一个cls接受当前的类,其他根据情况决定
返回值:通常返回对象或None
''' class MyClass2():
b = 2
obj2 = MyClass2() # (1) 基本语法
"""
借助object父类中的__new__魔术方法,创建对象
需要传递cls这个参数,代表的是本类,为本类创建对象,进行返回
"""
class MyClass():
a = 1
def __new__(cls):
print(cls) # <class '__main__.MyClass'>
# 借助父类object,里面的__new__魔术方法创建对象
# 1.返回本对象
return object.__new__(cls)
# 2.返回其他类的对象
# return obj2
# 3.不返回任何对象
# return None obj = MyClass()
print(obj)
# 返回本对象
# print(obj.a)
# 返回其他类对象
# print(obj.b) # (2) 验证__new__和__init__两个方法的触发时间
"""
__new__ 用来创建对象
__init__ 用来初始化对象的
先创建在初始化
__new__ 触发时机快于__init__
""" class MyClass():
def __new__(cls):
print(1)
return object.__new__(cls) def __init__(self):
print(2) obj = MyClass() # 传一个参数的情况
class MyClass():
def __new__(cls,name):
return object.__new__(cls) def __init__(self,name):
self.name = name obj = MyClass("周永玲") # 传多个参数的情况
class MyClass():
# 多个参数下,用收集参数来保证形参实参一一对应
def __new__(cls,*args,**kwargs):
return object.__new__(cls) def __init__(self,name,skin,age):
self.name = name
self.skin = skin
self.age = age
obj = MyClass("周玲玲","绿色",108)
print(obj.name) # 注意点:
"""
如果__new__返回的不是自己本类的对象,不会触发构造方法__init__
"""
class MyClass(): def __new__(cls,*args,**kwargs):
print("__new__被触发")
return obj2 def __init__(self):
print("__init__构造方法被触发")
obj = MyClass()
__new__魔术方法 示例代码
# ### 单态模式 : 无论实例化对象多少次,都有且只有一个对象 # (1) 基本语法
"""为了节省空间,加快效率,提出单态模式"""
class Singleton():
__obj = None
def __new__(cls):
if cls.__obj is None:
cls.__obj = object.__new__(cls)
return cls.__obj """
第一次实例化的时候,cls.__obj is None 返回True
执行object.__new__(cls) 返回对象 让cls.__obj接受对象
return 该对象 第二次实例化的时候,cls.__obj is None 返回False
return cls.__obj 内存中堆空间存放的对象返回 第三次实例化的时候,cls.__obj is None 返回False
return cls.__obj 内存中堆空间存放的对象返回 以后 .. 每次进行实例化的对象,都是第一次存储的那个对象
就实现了无论实例化几次,都返回同一个对象;
""" obj1 = Singleton()
obj2 = Singleton()
obj3 = Singleton()
print(obj1,obj2,obj3)
print(obj1 is obj2) # (2) 单态模式 + 构造方法
class Singleton():
__obj = None
def __new__(cls,*args,**kwargs):
if cls.__obj is None:
cls.__obj = object.__new__(cls)
return cls.__obj def __init__(self,name):
self.name = name obj1 = Singleton("李诗韵")
obj2 = Singleton("黄乐锡")
print(obj1.name)
print(obj2.name) """ 第一次实例化的时候, self.name = 李诗韵
第一次实例化的时候, 返回的是第一次实例化出来的对象
将该对象以前的name属性 从李诗韵改成黄乐西
self.name = 黄乐西 打印 obj1.name obj2.name 都是黄乐西 """
单态模式 示例代码
2. 类的魔术方法
# ### 魔术方法 __del__ (析构方法)
'''
触发时机:当对象被内存回收的时候自动触发[1.页面执行完毕回收所有变量 2.所有对象被del的时候]
功能:对象使用完毕后资源回收
参数:一个self接受对象
返回值:无
''' # (1) 基本使用
class Dog():
def __init__(self,name):
self.name = name def eatmeat(self):
print("小狗喜欢吃肉包子") def __del__(self):
print("析构方法被触发") # (1)页面执行完毕回收所有变量
obj = Dog("詹姆斯·蛋蛋")
obj.eatmeat() # (2)所有对象被del的时候
"""
两个变量指向同一个对象,其中删除obj这个变量的指向关系,
还有一个变量在指向该对象,所以对象没有被删除,不能够触发析构方法__del__
"""
obj2 = obj
print("===start===")
del obj
# del obj2
print("===end====") # (3)读取文件操作
import os
"""
fp = open("文件名",mode="r",encoding="utf-8")
res = fp.read()
fp.close()
"""
class ReadFile():
# 创建对象
def __new__(cls,filename):
if os.path.exists(filename):
return object.__new__(cls)
else:
return print("文件不存在")
# 打开文件
def __init__(self,filename):
self.fp = open(filename,mode="r",encoding="utf-8") # 读取文件
def readfile(self):
res = self.fp.read()
return res # 关闭文件
def __del__(self):
self.fp.close() obj = ReadFile("ceshi.txt")
res = obj.readfile()
print(res)
__del__析构方法 示例代码
# ###__call__ 魔术方法
'''
触发时机:把对象当作函数调用的时候自动触发
功能: 模拟函数化操作
参数: 参数不固定,至少一个self参数
返回值: 看需求
'''
# (1) 基本语法
class MyClass():
def __call__(self):
print("call方法被触发") obj = MyClass()
obj() # (2) 可以使用__call__统一调用方法,[模拟洗衣服的过程]
class Wash():
def __call__(self,something):
print("这是{}方法".format(something))
self.step1()
self.step2()
self.step3()
return "洗完了" def step1(self):
print("把衣服扔洗衣机里,把洗衣粉扔洗衣机里,搅拌") def step2(self):
print("加水,启动开关,把关门上") def step3(self):
print("把衣服拿出来,晒一晒")
obj = Wash()
"""
# 方法一
obj.step1()
obj.step2()
obj.step3()
"""
# 方法二
# obj()
res = obj("洗衣服")
print(res) # 模拟int方法,自定义类
import math
"""bool int float 字符串"""
class MyInt(): def myfunc(self,num,sign=1):
# print(num)
# print(sign)
res = num.lstrip("")
if res == "":
return 0
return eval(res) * sign def __call__(self,n): # 判断是不是bool
if isinstance(n,bool):
if n == True:
return 1
else:
return 0 # 判断是不是int
elif isinstance(n,int):
return n # 判断是不是float
elif isinstance(n,float):
if n > 0:
return math.floor(n)
else:
return math.ceil(n) # 判断是不是字符串
elif isinstance(n,str): # 判断是否带符号 + -
if (n[0] == "+" or n[0] == "-") and n[1:].isdecimal():
sign = None
# 获取符号
if n[0] == "+":
sign = 1
elif n[0] == "-":
sign = -1
return self.myfunc(n[1:],sign)
# 判断是否是纯数字字符串
elif n.isdecimal():
return self.myfunc(n)
else:
return "老弟,这个东西算不了." else:
return "脑弟,这个算不了" myint = MyInt()
res = myint(True)
res = myint(-19.89)
# res = myint("-abcddfdf")
# res = myint([1,2,3])
print(res,type(res))
__call__魔术方法 示例代码
# ### __str__ 魔术方法
'''
触发时机: 使用print(对象)或者str(对象)的时候触发
功能: 查看对象
参数: 一个self接受当前对象
返回值: 必须返回字符串类型
''' class Cat():
gift = "卖萌,喵喵喵"
def __init__(self,name):
self.name = name def cat_info(self):
return "小猫的名字{},小猫的天赋{}".format(self.name,self.gift) def __str__(self):
return self.cat_info() tom = Cat("汤姆")
# 方法一
print(tom)
# 方法二
res = str(tom)
print(res) # ### __repr__ 魔术方法
'''
触发时机: 使用repr(对象)的时候触发
功能: 查看对象,与魔术方法__str__相似
参数: 一个self接受当前对象
返回值: 必须返回字符串类型
'''
class Mouse():
gift = "偷油吃,下不来"
def __init__(self,name):
self.name = name def mouse_info(self):
return "小老鼠名字{},天赋{}".format(self.name,self.gift) def __repr__(self):
return self.mouse_info() # 在系统底层默认加了如下一句话
# __str__ = __repr__ jerry = Mouse("杰瑞")
res = repr(jerry)
print(res) print(jerry)
res = str(jerry)
print(res)
__str__魔术方法 示例代码
# ### __bool__ 魔术方法
'''
触发时机:使用bool(对象)的时候自动触发
功能:强转对象
参数:一个self接受当前对象
返回值:必须是布尔类型
'''
class MyClass():
def __bool__(self):
return False obj = MyClass()
res = bool(obj)
print(res) #__add__ 魔术方法 (与之相关的__radd__ 反向加法)
'''
触发时机:使用对象进行运算相加的时候自动触发
功能:对象运算
参数:二个对象参数
返回值:运算后的值
''' class MyClass():
def __init__(self,num):
self.num = num """对象在 加号+ 的左侧时,自动触发"""
def __add__(self,other):
print("add方法被触发")
"""
self 接受的是obj对象
other 接受的是数字
"""
# print(self)
# print(other)
return self.num + other """对象在 加号+ 的右侧时,自动触发"""
def __radd__(self,other):
"""
self 接受的是对象b
other 接受的是3
"""
return self.num + other * 3 # 5 + 3 * 3 = 14 # (1) add 方法
a = MyClass(10)
res = a + 1
print(res) # (2) radd方法
b = MyClass(5)
res = 3 + b
print(res) # (3) 对象 + 对象
"""
先触发add方法
self 接受a
other 接受b
return self.num + other => return 10 + b
res = 10 + b 后触发radd方法
self 接受b
other 接受10
return self.num + other * 3 => 5 + 10 *3 = 35
"""
res = a+b
print(res) #__len__ 魔术方法
'''
触发时机:使用len(对象)的时候自动触发
功能:用于检测对象中或者类中成员个数
参数:一个self接受当前对象
返回值:必须返回整型
'''
class MyClass():
pty1 = 1
pty2 = 2
__pty3 = 3 def func1():
print(1)
def func2():
pass
def __func3():
pass def __len__(self):
dic = MyClass.__dict__
print(dic)
"""
{
'__module__': '__main__',
'pty1': 1, 'pty2': 2, '_MyClass__pty3': 3,
'func1': <function MyClass.func1 at 0x7f99d664f6a8>,
'func2': <function MyClass.func2 at 0x7f99d664f730>,
'_MyClass__func3': <function MyClass.__func3 at 0x7f99d664f7b8>,
'__len__': <function MyClass.__len__ at 0x7f99d664f840>,
'__dict__': <attribute '__dict__' of 'MyClass' objects>,
'__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
'__doc__': None
}
"""
# 方法一
"""
lst = []
for i in dic:
if not( i.startswith("__") and i.endswith("__") ):
lst.append(i)
print(lst)
"""
# 方法二
lst = [ i for i in dic if not( i.startswith("__") and i.endswith("__") )]
return len(lst) obj = MyClass()
res = len(obj)
print(res)
__bool / add / len 魔术方法 __ 示例代码
day19
day19-Python运维开发基础(类的魔术方法)的更多相关文章
- Python运维开发基础09-函数基础【转】
上节作业回顾 #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 实现简单的shell命令sed的替换功能 import ...
- Python运维开发基础03-语法基础 【转】
上节作业回顾(讲解+温习60分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen #只用变量和字符串+循环实现“用户登陆 ...
- Python运维开发基础10-函数基础【转】
一,函数的非固定参数 1.1 默认参数 在定义形参的时候,提前给形参赋一个固定的值. #代码演示: def test(x,y=2): #形参里有一个默认参数 print (x) print (y) t ...
- Python运维开发基础08-文件基础【转】
一,文件的其他打开模式 "+"表示可以同时读写某个文件: r+,可读写文件(可读:可写:可追加) w+,写读(不常用) a+,同a(不常用 "U"表示在读取时, ...
- Python运维开发基础07-文件基础【转】
一,文件的基础操作 对文件操作的流程 [x] :打开文件,得到文件句柄并赋值给一个变量 [x] :通过句柄对文件进行操作 [x] :关闭文件 创建初始操作模板文件 [root@localhost sc ...
- Python运维开发基础06-语法基础【转】
上节作业回顾 (讲解+温习120分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 添加商家入口和用户入口并实现物 ...
- Python运维开发基础05-语法基础【转】
上节作业回顾(讲解+温习90分钟) #!/usr/bin/env python # -*- coding:utf-8 -*- # author:Mr.chen import os,time Tag = ...
- Python运维开发基础04-语法基础【转】
上节作业回顾(讲解+温习90分钟) #!/usr/bin/env python3 # -*- coding:utf-8 -*- # author:Mr.chen # 仅用列表+循环实现“简单的购物车程 ...
- Python运维开发基础02-语法基础【转】
上节作业回顾(讲解+温习60分钟) #!/bin/bash #user login User="yunjisuan" Passwd="666666" User2 ...
- Python运维开发基础01-语法基础【转】
开篇导语 整个Python运维开发教学采用的是最新的3.5.2版,当遇到2.x和3.x版本的不同点时,会采取演示的方式,让同学们了解. 教学预计分为四大部分,Python开发基础,Python开发进阶 ...
随机推荐
- Django+Celery+redis kombu.exceptions.EncodeError:Object of type is not JSON serializable报错
在本文中例子中遇到问题的各种开发版本如下: Python3.6.8 Django==2.2 celery==4.4.0 kombu==4.6.7 redis==3.3.0 大概的报错如下截图: 是在开 ...
- Tarjan-有向图
(我到底是咕了多少知识点啊) 在有向图中tarjan主要用来求强连通分量并缩点 一.定义 强连通:如果两个顶点可以相互通达,则称两个顶点 强连通 强连通分量:如果有向图G的每两个顶点都 强连通,称G是 ...
- word写文档体会
1.找一个文档规范要求. 2.根据文档的规范要求调整正文的格式,标题1的格式,标题2的格式,标题3的格式,图表的格式,把没用的那些格式都删除掉. 3.图注表注后空格一行. 4.设置页眉页脚. 5.生成 ...
- Go语言内置包之strconv
文章引用自 Go语言内置包之strconv Go语言中strconv包实现了基本数据类型和其字符串表示的相互转换. strconv包 strconv包实现了基本数据类型与其字符串表示的转换,主要有以下 ...
- Yii2.0 引入外部js css
<script src="<?= Yii::$app->request->baseUrl . '/js/jquery-2.1.1.min.js'?>" ...
- 【PAT甲级】1085 Perfect Sequence (25 分)
题意: 输入两个正整数N和P(N<=1e5,P<=1e9),接着输入N个正整数.输出一组数的最大个数使得其中最大的数不超过最小的数P倍. trick: 测试点5会爆int,因为P太大了.. ...
- LCT 维护边双 / 点双的模板
用 \(\text{LCT}\) 维护边双的做法是:加入一条非树边时,将这段树上路径合并为一个点代表这个边双,具体实现用并查集合并点,在 \(\text{Splay}\) 与 \(\text{Acce ...
- java -jar命令运行jar包时指定外部依赖jar包 linxux or windows
前尘回顾: setup.bat [chenquan@hostuser tartest]$ cat ../setup.sh javac -encoding UTF-8 -Djava.ext.dirs=. ...
- linux chrome rpm chrome浏览器下载(ver 63-70)
我的github chrome下载地址:https://github.com/chen1932390299/python 国内开源的资源 chrome下载centos 的:https://www.ch ...
- Unix系统级I/O
在Unix系统中,一且皆为文件.一个Linux文件就是一个字符序列,并且所有的I/O设备都被模型化成了文件.而所有的输入输出都被当作对对应文件的读和写.Linux提供了一组简单.低级的接口,使得所有的 ...