init
在创建对象的时候,自动调用对 创建的对象 进行初始化设置的
new 方法
class Test(object):
def __init__(self, a, b, c):
# 对‘对象‘做初始化的,__new__对象创建之后执行的
print('-------init------方法')
def __new__(cls, *args, **kwargs):
print('------new方法-------')
obj = super().__new__(cls)
return obj
Test(11, 22, 33)
#结果
------new方法-------
-------init------方法
参数:cls
cls 代表的是类对象本身
单例模式
类只能被实例化一次
实现思路
1.定义一个类属性,来记录该类创建的对象
2.__new__方法中,对步骤1中的类属性进行判断
1)没有创建过对象,那就从创建一个,并且把创建好的类赋值给步骤一中的类属性
2)如果已创建,就把创建好的类返回
实例化一个单例
#如果类属性__instance为None,那么就创建一个对象,并且赋值为这个对象的引用,保证下次调用这个方
法时能够知道之前已经创建过对象了,这样就保证了只有1个对象
class Test(object):
__instance = None
def __new__(cls, age, name):
if not cls.__instance:
cls.__instance = object.__new__(cls)
return cls.__instance
a = A()
b = A()
print(id(a))
print(id(b))
#运行结果:
4391023224
4391023224
上下文管理器
上下文管理器的概念:上下文管理器是一个Python对象,为操作提供了额外的上下文信息。 这种额外的信息, 在使用 with 语句初始化上下文,以及完成 with 块中的所有代码时,采用可调用的形式。
object.enter (self)
输入与此对象相关的运行时上下文。如果存在的话, with 语句将绑定该方法的返回值到该语句的
as 子句中指定的目标。
object.exit (self, exc_type, exc_val, exc_tb)
exc_type : # 异常类型
exc_val : # 异常值
exc_tb : # 异常回溯追踪
退出与此对象相关的运行时上下文。参数描述导致上下文退出的异常。如果该上下文退出时没有异常,三个参数都将为 None 。如果提供了一个异常,并且该方法希望抑制该异常(即防止它被传播),它应该返回一个真值。否则,在退出此方法后,异常将被正常处理。注意 exit() 方法不应该重新抛出传递进去的异常;这是调用者的责任。
上下文管理器实现:如果在一个类中实现了 enter , exit 这两个方法,那么这个类就实现了上下文管理器协议。
案例
class MyOpen:
def __init__(self, filename, mode, encoding='utf-8'):
self.f = open(filename, mode=mode, encoding=encoding)
def __enter__(self):
print('---enter---')
return self.f
def __exit__(self, exc_type, exc_val, exc_tb):
print('-----exit---')
print(exc_type,exc_val,exc_tb)
self.f.close()
with MyOpen('eee.txt', 'w', encoding='utf-8') as f:
# print(name)
f.write('222288888888888')
__call__方法
实现了该方法就可以调用
# ==============callable:判断对象是否可调用=============
# print(callable(d))
# print(callable(work))
class Demo:
def __call__(self, *args, **kwargs):
print('----call----')
def __init__(self,*args, **kwargs):
# 对‘对象‘做初始化的,__new__对象创建之后执行的
print('-------init------方法')
def __new__(cls, *args, **kwargs):
print('------new方法-------')
obj = super().__new__(cls)
return obj
d = Demo()
# 可调用的对象,加() 就会执行对象的__call__方法。
d() # d.__call__(d)
#结果
------new方法-------
-------init------方法
----call----
__str__方法
print打印的时候触发的是 str 方法
注意点:
重写`str,必须要记得写return。
return返回的必须是一个字符串对象。
内置函数str转换一个对象时,触发对象对应 str 的方法。
内置函数format处理对象是,触发对象对应 str 的方法。
class Demo:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
"""对象被输出到控制台时,显示的内容有该方法决定
改方法返回值必须是一个字符串
"""
return self.name
d = Demo('张三', 18)
d2 = Demo('李四', 18)
print(d)
print(d2)
#结果
#未实现__str__时返回
<__main__.Demo object at 0x000001867F046390>
<__main__.Demo object at 0x000001867F0465F8>
#实现__str__后返回
张三
李四
__repr__方法
class Demo2:
def __str__(self):
return '1111'
def __repr__(self):
"""返回对象的原始信息"""
return '字符串121212'
d = Demo2()
print(d)
print(repr(d))
st = 'python'
print(st)
print(repr(st))
#结果
1111
字符串121212
python
'python'
算术运算符触发的魔术方法
#对象相加触发的魔术方法是:add
#对象相减触发的魔术方法是:sub
# 自定义一个可以进行相减的字符串类
class MyStr(str):
def __sub__(self, other):
return self.replace(other, '')
aa = MyStr('123456')
bb = MyStr("123")
cc = aa - bb
print(cc)
#结果
456
class Test(object):
def __init__(self, name, age):
self.name = name
self.age = age
def __add__(self, other):
"""返回两个对象的age之和"""
print('对象之间使用了+号')
return self.age + other.age
xiaoming = Test('小明', 18)
laowang = Test('老王', 48)
res = xiaoming + laowang
print(res)
#结果
对象之间使用了+号
66