python进阶--魔法方法之类的表示

下面的魔法方法都可以用了描述类

1、__str__

该方法一般返回字符串,也许不会返回一个有效的 Python 表达式,但可以使用更方便或更准确的描述信息。在类中重写该方法,用来输出类的属性值等信息

调用:str(object)或者内置函数format()或者print()都会调用__str__()方法

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def describe(self):
        print('名字:'+self.name + ',年龄:' + str(self.age))

    #重写_str__函数
    def __str__(self):
        return 'str:'+'名字:'+self.name + ',年龄:' + str(self.age)


if __name__ == '__main__':
    p = Person('Joy', 25)
    print(p)
    #print(str(p))

    p.describe()

输出:
str:名字:Joy,年龄:25
名字:Joy,年龄:25
2、__repr__

用来输出一个对象的“官方”字符串表示。返回值必须是字符串对象此方法通常被用于调试。内置类型 object 所定义的默认实现会调用 object.__repr__()
调用:通过repr()调用

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def describe(self):
        print('名字:'+self.name + ',年龄:' + str(self.age))

    #重写_str__函数
    def __str__(self):
        return 'str:'+'名字:'+self.name + ',年龄:' + str(self.age)

        # 重写_str__函数
    def __repr__(self):
        return 'repr:'+'名字:' + self.name + ',年龄:' + str(self.age)


if __name__ == '__main__':
    p = Person('Joy', 25)
    print(str(p))
    print(repr(p))

    p.describe()

输出:
str:名字:Joy,年龄:25
repr:名字:Joy,年龄:25
名字:Joy,年龄:25

__str__和__repr__都是用来输出一个对象,但是也有一些区别,描述如下

  • __str__ 的目标是可读的,__str__()并不预期返回一个有效的 Python 表达式,但可以使用更方便或更准确的描述信息。
  • __repr__ 的目标是明确的,所返回的字符串应该准确、无歧义,并且尽可能表达出如何 用代码创建出这个被打印的对象。
  • 容器的 str 方法的使用包含对象的 repr
3、__unicode__()

定义对类的实例调用 unicode() 时的行为,返回unicode字符串,在对象上调用unicode()时就会调用__ unicode__()方法。一般项目中使用Django时,我们通常会在mode类中重写__ unicode__()方法,因为Django的数据库后端会返回Unicode字符串给model属性。

如果调用 str() ,但类只实现了 __unicode__() ,那么将会报错,需要实现__ str__()。,但是在Django项目中可以只定义了__ unicode__()方法,不定义__ str__()方法,因为Django会自动提供一个调用 __ unicode__()方法的__ str__()方法,用于把结果转换为UTF-8编码的字符串对象,所以在一般情况下,只定义__ unicode__()方法,让 Django来处理字符串对象的转换

Python3x中使用__ str__()方法替代__unicode__()方法

#运行环境为python2x
class Person():
    def __init__(self, name):
        self.name = name

    def __unicode__(self):
        return "name:"+self.name


obj = Person("Hello, Unicode!")
print(unicode(obj))  

输出:name:Hello, Unicode!
4、__format__()

定义当类的实例用于新式字符串格式化时的行为,调用format() 会导致调用 __format__() 。在定义自己的数值类型或字符串类型时,并且需要提供某些特殊的格式化选项,使用 __format__()方法可以很容易实现

class point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return 'x: %s, y: %s' % (self.x, self.y)

    def __format__(self, code):
        print "__format__"
        return 'x: {x}, y: {y}'.format(x=self.x, y=self.y)

p = point(3, 4)
print ('point is {}'.format(p))

输出:
__format__
point is x: 3, y: 4

分析:由于format当中支持通过参数来对处理逻辑进行配置的功能,所以在__format__()多加了一个参数code,我们就可以直接调用format(p)

在有些场景中我们需要提供多种输出,比如下面例子

formats = {
    'normal': 'x: {p.x}, y: {p.y}',
    'point': '({p.x}, {p.y})',
    'prot': '<{p.x}, {p.y}>'
}

class point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

    def __str__(self):
        return 'x: %s, y: %s' % (self.x, self.y)

    def __format__(self, code):
        return formats[code].format(p=self)


p = point(3, 4)
print (p.__format__('normal'))
print (p.__format__('point'))

输出:
x: 3, y: 4
(3, 4)
5、__nonzero__()

__nonzero__()定义了类的实例调用 bool() 时的行为,在设计自己的类时,使用该方法针对不同的实例返回True或False

在Python 3.x中,__nonzero__方法被__bool__方法替代

__bool__()__nonzero__()类似,定义了类的实例调用 bool() 时的行为,调用此方法来实现真值检测以及内置的 bool() 操作;应该返回 False 或 True, 当未定义此方法时,则在定义了 __len__() 的情况下将调用它,如果其结果不为零则该对象将被视为具有真值。

如果一个类的 __len__()__bool__() 均未定义,则其所有实例都将被视为具有真值。

>>> class test:
>>>     def __bool__(self):
>>>         return False

>>> bool(test())
False
>>> not test()
True
6、__hash__()和__dir__()方法

__hash__(self)__dir__(self)方法,在定义类的时候很少用到,我们这里就不展开描述了,了解其作用即可
(1)__hash__(self)
必须返回整数,其结果会被用于字典中键的快速比较;作用是定义对类的实例调用 hash() 时的行为。同时注意一点,实现这个魔法方法通常也需要实现 __eq__ ,并且遵守如下的规则: a == b 意味着 hash(a) == hash(b)。

(2)__dir__(self)
这个方法应该向调用者返回一个属性列表;作用是定义对类的实例调用 dir() 时的行为。一般来说,没必要自己实现 __dir__ 。但是如果你重定义了 __getattr__ 或者 __getattribute__ ,乃至使用动态生成的属性,以实现类的交互式使用,那么这个魔法方法是必不可少的。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序员的修养

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值