python常见类内置方法

python类内置方法

1、new() 、init()

__new__方法用于产生实例化对象(空属性),在创建实例对象的时候调用。重写__new__方法可以控制对象的产生过程,在单例模式中起很大作用。
__init__方法是初始化方法,负责对实例化对象进行属性值初始化,重写__init__方法可以控制对象的初始化过程。
__init__没有返回值,__new__方法必须返回一个对象。

class A(object):

    def __init__(self):
        print("调用__init__")

    def __new__(cls, *args, **kwargs):
        print("调用__new__")
        return super(A, cls).__new__(cls, *args, **kwargs)


if __name__ == '__main__':
    s = A()

# 输出结果
# 调用__new__
# 调用__init__

单例模式:

class Single(object):

    def __new__(cls, *args, **kwargs):
        if not hasattr(cls, '_instance'):
            cls._instance = super(Single, cls).__new__(cls)
        return cls._instance


class A(Single):

    def __init__(self):
        pass


a = A()
b = A()
print(id(a))  # 4347816720
print(id(b))  # 4347816720

2、str()、repr()

两者的目的都是为了显式的显示对象的一些必要信息,方便查看和调试。__str__被print默认调用,__repr__被控制台输出时默认调用。即,使用__str__控制用户展示,使用__repr__控制调试展示。

class A(object):

    def __str__(self):
        return "class A"


if __name__ == '__main__':
    s = A()
    print(s)

# 输出结果
# class A

class A(object):

    def __init__(self):
        self.a = 12


if __name__ == '__main__':
    s = A()
    print(s)  # 默认调用object的__repr__方法

# 输出结果
# <__main__.A object at 0x108dc6910>

# 重写repr方法与str,效果与str一样,同时重写的话print调用__str__
class A(object):

    def __init__(self):
        self.a = 12

    def __repr__(self):
        return "pppppp"


if __name__ == '__main__':
    s = A()
    print(s)

# 输出结果
# pppppp

3、call()

__call__方法提供给对象可以像函数那样被执行的能力。在类装饰器中有很大作用。

class A(object):

    def __call__(self, *args, **kwargs):
        print(args)
        print(kwargs)
        return "__call__被执行了"


if __name__ == '__main__':
    s = A()
    print(s(1, 2, 3, a=11, b=33))

# 输出结果
# (1, 2, 3)
# {'a': 11, 'b': 33}
# __call__被执行了

类装饰器:

class B(object):
    def __init__(self, *args, **kwargs):
        print("__init__")
        print(args)
        print(kwargs)
        print("__init__")

    def __call__(self, func):
        print("__call__")

        def inner(*args, **kwargs):
            print(args)
            print(kwargs)
            return func(*args, **kwargs)

        return inner


@B('xiaowang', age=12)
def hello(name, age=15):
    print("hello")
    print(name)
    print(age)
    print("hello")


hello('laowang', age=16)
# 输出:
# __init__
# ('xiaowang',)
# {'age': 12}
# __init__
# __call__
# ('laowang',)
# {'age': 16}
# hello2
# laowang
# 16
# hello2

4、del()

__del__用于当对象的引用计数为0时自动调用。
__del__一般出现在两个地方:1、手工使用del减少对象引用计数至0,被垃圾回收处理时调用。2、程序结束时调用。
__del__一般用于需要声明在对象被删除前需要处理的资源回收操作。

class A(object):

    def __del__(self):
        print("类A的对象被删除了")


class B(object):

    def __del__(self):
        print("类B的对象被删除了")


if __name__ == '__main__':
    a = A()
    b = B()
    del b

# 输出结果
# 类B的对象被删除了
# 类A的对象被删除了

5、iternext

这2个方法用于将一个对象模拟成序列。重写这两个方法就可以实现自定义的迭代对象。
__next__实现斐波那契生成器函数

import sys


def fibonacci(n):  # 生成器函数 - 斐波那契
    a, b, counter = 0, 1, 0
    while True:
        if counter > n:
            return
        yield a
        a, b = b, a + b
        counter += 1


if __name__ == '__main__':

    f = fibonacci(10)  # f 是一个迭代器,由生成器返回生成
    while True:
        try:
            print(next(f), end=" ")
        except StopIteration:
            sys.exit()
    # 0 1 1 2 3 5 8 13 21 34 55 

自定义迭代器

class MyNumbers(object):
    def __iter__(self):
        self.a = 1
        return self

    def __next__(self):
        if self.a <= 20:
            b, self.a = self.a, self.a + 1
            return b
        else:
            raise StopIteration


if __name__ == '__main__':

    # 实例化自定义迭代器
    myclass = MyNumbers()
    # 创建迭代器对象
    myiter = iter(myclass)

    for i in myiter:
        print(i, end="  ")
    # 1  2  3  4  5  6  7  8  9  10  11  12  13  14  15  16  17  18  19  20

6、getitemsetitemdelitem

__getitem__(self, key)这个方法应返回与指定键相关联的值。对序列来说,键整数(也可以是负数),对映射来说,键可以是任何类型。
__setitem__(self, key,value):这个方法应以与键相关联的方式存储值,以便以后能够使用__getitem__来获取。
__delitem__(self, key):这个方法在对对象的组成部分使用__del__语句时被调用,应删除与key相关联的值。

class A(object):

    def __init__(self, name, age):
        self.name = name
        self.age = age
        self.stu = {name: age}

    def __getitem__(self, item):
        return self.stu.get(item)

    def __setitem__(self, key, value):
        self.stu[key] = value

    def __delitem__(self, key):
        del self.stu[key]


if __name__ == '__main__':
    a = A('XiaoWang', 12)
    print(a.stu)            # {'XiaoWang': 12}
    print(a['XiaoWang'])    # 12
    a['LaoWang'] = 54
    print(a.stu)            # {'XiaoWang': 12, 'LaoWang': 54}
    del a['XiaoWang']
    print(a.stu)            # {'LaoWang': 54}

7、getattrsetattrdelattr

当使用obj.x = y的时候触发对象的setattr方法,当del obj.x的时候触发对象的delattr方法。
当尝试访问对象的一个不存在的属性时会触发getattr方法,可以重写这3个方法来控制对象属性的访问、设置和删除。

class A(object):

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

    def __getattr__(self, item):
        return "%s属性不存在!" % item

    def __setattr__(self, key, value):
        print("设置%s属性的值为%s" % (key, value))
        super(A, self).__setattr__(key, value)

    def __delattr__(self, item):
        print("删除属性%s" % item)
        super(A, self).__delattr__(item)


if __name__ == '__main__':
    a = A('XiaoWang', 12) 
    # 设置name属性的值为XiaoWang
    # 设置age属性的值为12
    print(a.height)  
    # height属性不存在!
    a.age = 99
    # 设置age属性的值为99
    del a.name
    # 删除属性name


版权声明:本文为kylinxjd原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。