下面的魔法方法都可以用了描述类
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)。文章来源:https://www.toymoban.com/news/detail-679640.html
(2)__dir__(self)
这个方法应该向调用者返回一个属性列表;作用是定义对类的实例调用 dir() 时的行为。一般来说,没必要自己实现 __dir__
。但是如果你重定义了 __getattr__
或者 __getattribute__
,乃至使用动态生成的属性,以实现类的交互式使用,那么这个魔法方法是必不可少的。文章来源地址https://www.toymoban.com/news/detail-679640.html
到了这里,关于python进阶--魔法方法之类的表示的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!