高阶编程(八):魔术方法

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值