内置方法

PythonClass机制内置了很多特殊的方法来帮助使用者高度定制自己的类,这些内置方法都是以双下划线开头和结尾的,会在满足某种条件时自动触发

__str__

含义

__str__方法会在对象被打印(print)操作的时候,自动触发,该方法必须返回字符串类型的数据。很多时候用来更加精准的描述对象

使用

class MyClass(object):
    def __init__(self, name):
        self.name = name

    def __str__(self):
        """该方法必须返回字符串类型的数据"""
        return "对象:%s" % self.name


obj = MyClass('kevin')

# print(obj)  # (没有__str__)
# <__main__.MyClass object at 0x7fd2bb457860>

print(obj)
# 对象:kevin
print(MyClass)
# <class '__main__.MyClass'>

__del__

含义

__del__方法会在对象被执行(被动、主动)删除操作之后自动执行。

Python的垃圾回收机制会自动清理Python程序的资源,当一个对象只占用应用程序级资源时,完全没必要为对象定制__del__方法,但在产生一个对象的同时涉及到申请系统资源(比如系统打开的文件、网络连接等)的情况下,关于系统资源的回收,Python的垃圾回收机制便派不上用场了,需要我们为对象定制该方法,用来在对象被删除时自动触发回收系统资源的操作

使用

被动删除

class MyClass(object):
    def __init__(self, name):
        self.name = name

    def __del__(self):
        """对象被执行删除操作之后执行(垃圾回收机制)"""
        print("__del__什么时候执行")


obj = MyClass('kevin')

print("被动删除")
# 被动删除
# __del__什么时候执行

主动删除

class MyClass(object):
    def __init__(self, name):
        self.name = name

    def __del__(self):
        """对象被执行删除操作之后执行"""
        print("__del__什么时候执行")


obj = MyClass('kevin')
"""主动删除"""
del obj
# __del__什么时候执行
print("主动删除")
# 主动删除

__getattr__

含义

__getattr__方法会在对象查找不存在的“名字”时候自动触发

使用

class MyClass(object):
    def __init__(self, name):
        self.name = name

    def __getattr__(self, item):
        """对象查找不存在名字的时候自动触发"""
        return "不好意思,没有%s这个名字" % item  # item 表示不存在的"名字",类型是字符串


obj = MyClass('kevin')
print(obj.name)
# kevin

print(obj.age)
# 不好意思,没有age这个名字

__setattr__

含义

__setattr__方法在对象添加属性操作的时候自动触发

使用

class MyClass(object):
    def __init__(self, name):
        self.name = name

    def __setattr__(self, key, value):
        """对象在执行添加属性操作的时候自动触发>>>obj.变量名=变量值"""
        print("__setattr__方法")
        print(key, value)


obj = MyClass('kevin')
# __setattr__方法
# name kevin

print(obj.__dict__)  # 因为重写了__setattr__,赋值操作都会触发它的运行,根本没赋值,除非直接接操作属性字典,否则永远无法赋值
# {}

obj.age = 22
# __setattr__方法
# age 22
print(obj.__dict__)  # 因为重写了__setattr__,赋值操作都会触发它的运行,根本没赋值,除非直接接操作属性字典,否则永远无法赋值

obj.__dict__['name'] = 'tony'
print(obj.__dict__)
# {'name': 'tony'}

__call__

含义

__call__方法在对象被加括号调用的时候自动触发

使用

class MyClass(object):
    def __init__(self, name):
        self.name = name

    def __call__(self, *args, **kwargs):
        """在对象被加括号的时候自动触发"""
        print("__call__方法", args, kwargs)


obj = MyClass('kevin')
obj()
# __call__方法 () {}

__enter____exit__

含义

__enter__方法在对象被执行with上下文管理语法开始自动触发 ,该方法返回什么as后面的变量名就会得到什么

__exit__方法在对象被执行with上下文管理语法结束之后自动触发

使用

class MyClass(object):
    def __init__(self, name):
        self.name = name

    def __enter__(self):
        print("__enter__方法")

    def __exit__(self, exc_type, exc_val, exc_tb):
        print("__enter__方法")


obj = MyClass('kevin')

with obj as f:
    print("开始前触发")
print("结算后触发")

# __enter__方法
# 开始前触发
# __enter__方法
# 结算后触发

__getattribute__

含义

只要对象查找名字无论名字是否存在都会执行该方法,如果类中有__getattribute__方法那么就不会去执行__getattr__方法

使用

class MyClass(object):
    def __init__(self, name):
        self.name = name

    def __getattr__(self, item):
        print(print("__getattr__方法", item))

    def __getattribute__(self, item):
        print("__getattribute__方法")
        return "这个名字是%s" % item


obj = MyClass('kevin')
print(obj.name)
# __getattribute__方法 name
# 这个名字是name

__new__

含义

__new__用于产生空对象(并不是所有的地方都可以直接调用__new__ 该方法过于底层)

使用

# 在元类__new__里面,可以直接调用
class Meta(type):
    def __new__(cls, *args, **kwargs):
        obj = type.__new__(cls, *args, **kwargs)
        return obj
        # 如果是在元类的__call__里面 需要间接调用


class Mate(type):
    def __call__(self, *args, **kwargs):
        obj = object.__new__(self)  # 创建一个空对象
        self.__init__(obj, *args, **kwargs)  # 让对象去初始化
        return obj

笔试题

笔试题一

让字典具备句点符查找值的功能,

# 定义一个类继承字典
class MyDict(dict):
    def __getattr__(self, item):
        return self.get(item)

    def __setattr__(self, key, value):
        self[key] = value

'''要区别是名称空间的名字还是数据k:v键值对'''
obj = MyDict({'name': 'kevin', 'age': 22})

# 1.具备句点符取v
print(obj.name)
# kevin


# 2.具备句点符设k:v
obj.gender = 'male'
print(obj)
# {'name': 'kevin', 'age': 22, 'gender': 'male'}

笔试题二

补全下列代码 使其运行不报错

"""
class Context:
    pass
with Context() as ctx:
    ctx.do_something()
"""


class Context:
    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_val, exc_tb):
        pass

    def do_something(self):
        pass


with Context() as ctx:
    ctx.do_something()
Last modification:April 15, 2022
如果觉得我的文章对你有用,请随意赞赏