Python __new__ 方法解释与使用

597 篇文章 17 订阅
100 篇文章 2 订阅

解释

我们通常把__init__ 称为构造方法,这是从其他语言借鉴过来的术语。

其实,用于构建实例的是特殊方法__new__:这是个类方法(使用特殊方式处理,因此不必使用 @classmethod 装饰器),必须返回一个实例。返回的实例会作为第一个参数(即 self)传给__init__ 方法。

因为调用__init__方法时要传入实例,而且禁止返回任何值,所以 __init__方法其实是“初始化方法”。真正的构造方法是 __new__

我们几乎不需要自己编写__new__方法,因为从 object 类继承的实现已经足够了。刚才说明的过程,即从__new__ 方法到__init__方法,是最常见的,但不是唯一的。__new__方法也可以返回其他类的实例,此时,解释器不会调用__init__方法。

也就是说,Python 构建对象的过程可以使用下述伪代码概括:

# 构建对象的伪代码 
def object_maker(the_class, some_arg):     
	new_object = the_class.__new__(some_arg)     
	if isinstance(new_object, the_class):         
		the_class.__init__(new_object, some_arg)     
	return new_object 
 
# 下述两个语句的作用基本等效 
x = Foo('bar') 
x = object_maker(Foo, 'bar')

示例:对JSON的解析

import keyword


class FrozenJSON(object):
    """一个只读接口
    使用属性表示访问JSON类对象
    """

    def __init__(self, mapping):
        self._data = {}
        for k, v in mapping.items():
            if keyword.iskeyword(k):
                k += '_'
            self._data[k] = v

    def __getattr__(self, name):
        if hasattr(self._data, name):
            return getattr(self._data, name)
        else:
            return FrozenJSON.build(self._data[name])

    @classmethod
    def build(cls, obj):
        if isinstance(obj, abc.Mapping):
            return cls(obj)
        elif isinstance(obj, abc.MutableSequence):
            return [cls.build(item) for item in obj]
        else:
            return obj


class FrozenJSON2(object):
    """通过定义 __new__ 方法完成实例创建时的行为"""
    def __new__(cls, arg):
        if isinstance(arg, abc.Mapping):
            return super().__new__(cls)
        elif isinstance(arg, abc.MutableSequence):
            return [cls(item) for item in arg]
        else:
            return arg

    def __init__(self, mapping):
        self._data = {}
        for k, v in mapping.items():
            if keyword.iskeyword(k):
                k += '_'
            self._data[k] = v

    def __getattr__(self, name):
        if hasattr(self._data, name):
            return getattr(self._data, name)
        else:
            return FrozenJSON(self._data[name])

在这里插入图片描述
希望本文对你有所帮助~~如果对软件测试、接口测试、自动化测试、面试经验交流感兴趣可以加入我们。642830685,免费领取最新软件测试大厂面试资料和Python自动化、接口、框架搭建学习资料!技术大牛解惑答疑,同行一起交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值