Python语法层面的一些协议

每个编程语言都有自己的最佳实践.通常你不能套用别的语言来写出pythonic的代码.

Python 是一门初学简单,越学越难的语言.

Python的世界中, 万物皆对象.当我们说某个对象是什么类型时,在根本上其实指的是:这个对象满足了该类型的特定接口规范,可以被当成这个类型来使用.

如何定义一个对象的特定接口呢?

dunder methods, 即双下划线方法.

Python 的对象定义了非常多的双下划线方法,比如 __init__/__eq__/__hash__ 等等,接下来进行实战中常见一个小总结

__str__

当对象定义了以上协议,就可以使用str函数,打印自定义的结果

class Foo:
    def __str__(self):
        return 'my name is bingo!'

print(Foo())

__format__

将对象表示成字符串,有利于开发者理解

# 额外定义展示格式:long/short.其中long打印出当前对象在内存中的位置
class Foo:
    def __format__(self, fmt):
        if fmt == 'long':
            return 'I am a Foo instance, I stay at {}'.format(id(self))
        elif fmt == 'short':
            return 'I am a Foo instance.'

f1 = Foo()
f2 = Foo()

print('{:long}'.format(f1))
# I am a Foo instance, I stay at 139870957014152
print('{:short}'.format(f2))
# I am a Foo instance.

__bool__

当对象定义了以上协议,在进行布尔判断时,使用自定义的逻辑

class Foo:
    def __bool__(self):
        return True # 当进行布尔判断时,永远返回True.仅仅是一个示例,没有实际价值
if Foo():
    print('yes')
# yes

__enter__ 和 __exit__

当对象定义了以上两种协议时,此对象可以作为上下文文件管理器

__hash__  __eq__

当对象定义了以上两种协议时, 此对象可以作为可哈希对象,可以作为字典的键和集合的元素.

来自 腾讯技术专栏 的一个例子.这个例子需要使用集合的差集计算,所以需要实现上述两个协议.

class VisitRecord:
    """旅游记录
    """
    def __init__(self, first_name, last_name, phone_number, date_visited):
        self.first_name = first_name
        self.last_name = last_name
        self.phone_number = phone_number
        self.date_visited = date_visited

    def __hash__(self):
        return hash(
            (self.first_name, self.last_name, self.phone_number)
        )
    def __eq__(self, other):
        # 当两条访问记录的名字与电话号相等时,判定二者相等。
        if isinstance(other, VisitRecord) and hash(other) == hash(self):
            return True
        return False
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值