python中一些特殊方法的作用

我们先暂且称呼为特殊方法。

单下划线开头(_foo)双下划线开头的(__foo)双下划线开头和结尾的( __foo__)
代表不能直接访问的类属性,需通过类提供的接口进行访问,不能用“from xxx import *”而导入;代表类的私有成员代表python里特殊方法专用的标识,如 _init_()代表类的构造函数

1 __repr__方法

_repr__是类的内建方法,所有的类都是继承自Object类,因此在外部调用时,需要使用repr函数,好比Node类通过重写__repr_,从而重写了repr。
这是文档上标注的,因为理解不太贴切,所以还是放上官方介绍吧。

Return a string containing a printable representation of an object.
For many types, this function makes an attempt to return a string that would yield an object with the same value when passed to eval(), otherwise the representation is a string enclosed in angle brackets that contains the name of the type of the object together with additional information often including the name and address of the object.
A class can control what this function returns for its instances by defining a repr() method.

class Node(object):
    def __init__(self, value, flag = 1):
        self._value = value
        self._children = []
        self._flag = flag
    def add_child(self, node):
        self._children.append(node)
    def __repr__(self):
        return 'Node({!r})'.format(self._value)

if __name__ == '__main__':
    n1 = Node(0)
    print(n1)
    #Node(0)

2 str 方法

此方法返回对象的字符串表示形式。在对象上调用print()或str()函数时调用此方法。
这个方法必须返回String对象。如果我们没有为类实现_str__()函数,那么使用内置的对象实现来实际调用_repr__()函数。

3 str and repr example

我们注意到无论是__str__还是__repr__方法,返回的都要求是str类型

class Person(object):
    name = ""
    age = 0

def __init__(self, personName, personAge):
    self.name = personName
    self.age = personAge

def __repr__(self):
    return '{name'+self.name + ',' + 'age:' + str(self.age) + '}'

def __str__(self):
    return 'Person(name=' + self.name + ', age=' + str(self.age) + ')'

p = Person('Pankaj', 34)
# __str__() example
print(p) #Person(name=Pankaj, age=34)
# print(p.__str__())#Person(name=Pankaj, age=34)
# s = str(p)
# print(s)#Person(name=Pankaj, age=34)
#
# # __repr__() example
# print(p.__repr__())
# print(type(p.__repr__()))
# print(repr(p))

we mentioned that if we don’t implement str function then the repr function is called. Just comment the str function implementation from Person class and print§ will print {name:Pankaj, age:34}.我们发现,__str__的优先级是大于__repr__的。

4 python 类中的self是是什么

self指的是类实例对象本身(注意:不是类本身)。

5 python3中的__slots__

当一个类需要创建大量实例时,可以通过__slots__声明实例所需要的属性,

例如,class Foo(object): slots = [‘foo’]。这样做带来以下优点:

  • 更快的属性访问速度
  • 减少内存消耗

使用__slots__也是有副作用的:

1. 每个继承的子类都要重新定义一遍__slots__
2. 实例只能包含哪些在__slots__定义的属性,这对写程序的灵活性有影响,比如你由于某个原因新网给instance设置一个新的属性,比如instance.a = 1, 但是由于a不在__slots__里面就直接报错了,你得不断地去修改__slots__或者用其他方法迂回的解决
3. 实例不能有弱引用(weakref)目标,否则要记得把__weakref__放进__slots__

另外参考:https://zhuanlan.zhihu.com/p/25930288

6. __call__方法

一个函数(甚至对象)之所以能执行,关键就在于 call() 方法。实际上 x(arg1, arg2,…) 只是 x.call(arg1, arg2, …) 的快捷写法,因此我们甚至可以为自定义类添加 _call_ 方法,从而使得该类的实例也变成可调用的。例如如下代码:

# 定义Role类
class Role:
    def __init__ (self, name):
        self.name = name
    # 定义__call__方法
    def __call__(self):
        print('执行Role对象')
r = Role('管理员')
# 直接调用Role对象,就是调用该对象的__call__方法
r()# 执行Role对象

上面程序中最后一行代码使用调用函数的语法来调用对象,这看上去似乎是错误的,但由于该 Role 类提供了\ call 方法,因此调用对象的本质就是执行该对象的 _call_ 方法。运行上面代码,将看到如下输出结果:

对于程序中的函数,同样既可使用函数的语法来调用它,也可把函数当成对象,调用它的 call 方法。例如如下示例代码:

def foo ():
    print('--foo函数--')
# 下面示范了2种方式调用foo()函数
foo()
foo.__call__()
运行上面代码,可以看到 foo() 和 foo.__call__() 的效果完全相同。

7. 对象表现形式(bytes)

在 Python 3 中,

  • _repr_、_str_ 和 _format_ 都必须返回 Unicode 字符串(str 类型)。
  • 只有_bytes_ 方法应该返回字节序列(bytes 类型)。

8.str.format()的简单用法

字段名:省略;数字;变量名

‘name is {}, age is {}’.format(‘peter’,25)
‘name is {1}, age is {0}’.format(25, ‘peter’)
‘name is {name}, age is {age}’.format(name=‘peter’,age=‘25’)

转换字段: !s !r !a

  • s:传递参数之前先对参数调用 str()
  • r:传递参数之前先对参数调用 repr()
  • a:传递参数之前先对参数调用 ascii()

例子:

class Person:
    def __init__(self, name, age):
        self.name = name
        self.age = age
        
    def __repr__(self):
        return 'Person({0.name!r}, {0.age!r})'.format(self)
    
    def __str__(self):
        return '({0.name!s}, {0.age!s})'.format(self)
    
person = Person('peter', 25)
'this person is {!r}'.format(person)
'this person is {!s}'.format(person)
'this person is {!a}'.format('皮特')

# result
"this person is Person('peter', 25)"
'this person is (peter, 25)'
"this person is '\\u76ae\\u7279'"
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值