魔方方法篇第一章--------构造与析构

我们最为熟知的基本的魔法方法就是 __init__ ,我们可以用它来指明一个对象初始化的行为。然而,当我们调用 x = SomeClass() 的时候, __init__ 并不是第一个被调用的方法。事实上,第一个被调用的是 __new__ ,这个 方法才真正地创建了实例。当这个对象的生命周期结束的时候(指类被删除之后), __del__ 会被调用。让我们近一步理解这三个方法:

__new__(cls,[...)
__new__ 是对象实例化时第一个调用的方法,它只取下 cls 参数,并把其他参数传给 __init__ 。 __new__ 很少使用,但是也有它适合的场景,尤其是当类继承自一个像元组或者字符串这样不经常改变的类型的时候。我不打算深入讨论 __new__ ,因为它并不是很有用, Python文档 中 有详细的说明。

__init__(self,[...])
类的初始化方法。它获取任何传给构造器的参数(比如我们调用 x = SomeClass(10, ‘foo’) , __init__ 就会接到参数 10 和 ‘foo’ 。 __init__ 在Python的类定义中用的最多。

__del__(self)
__new__ 和 __init__ 是对象的构造器, __del__ 是对象的销毁器。它并非实现了语句 del x (因此该语句不等同于 x.__del__())。而是定义了当对象被垃圾回收时的行为。 当对象需要在销毁时做一些处理的时候这个方法很有用,比如 socket 对象、文件对象。但是需要注意的是,当Python解释器退出但对象仍然存活的时候, __del__ 并不会 执行。 所以养成一个手工清理的好习惯是很重要的,比如及时关闭连接。

看下面例子,关于__new__ 和 __init__ 的调用会有一些理解:

class Ceshi1:
    def __new__(cls, *args, **kwargs):
        print("__new__正在调用")
        return object.__new__(cls, *args, **kwargs)
    def __init__(self):
        print("__init__正在调用")
    def __del__(self):
        print("__del__正在调用")

以下是运行过程

>>> c = Ceshi1()__new__正在调用__init__正在调用>>> del c__del__正在调用
class Person(object):
    def __new__(cls, name, age):
        print(‘__new__在实例化之前被调用。‘)
        return object.__new__(cls)

    def __init__(self, name, age):
        print("__init__在实例化后被调用。")
        self.name = name
        self.age = age

    def __str__(self):
        return f‘<人物是{self.name},年龄为{self.age}>‘

    def __del__(self):
        print("调用__del__魔法")

以下是运行过程:

# >>> c = Person("Tony",24)# __new__在实例化之前被调用。# __init__在实例化后被调用。# >>> print(c)# <人物是Tony,年龄为24># >>> del c# 调用__del__魔法
class Foo:
    def __new__(cls, *args, **kwargs):
        print("__new__正在调用")
        print(cls)
        print(object.__new__(cls, *args, **kwargs))
        return object.__new__(cls, *args, **kwargs)
    def __init__(self):
        print("__init__正在调用")
        print(self)
foo = Foo()
#================运行如下=============# __new__正在调用# <class ‘__main__.Foo‘># <__main__.Foo object at 0x0000000003070F28># __init__正在调用# <__main__.Foo object at 0x0000000003070F28># 总结先执行__new__方法,再执行__init__方法。实例化是在__new__中完成的,进入__init__时,self已经实例化了。=================================分割线===================================================
__new__(cls,[...)   __new__ 是对象实例化时第一个调用的方法,它只取下 cls 参数,并把其他参数传给 __init__第一个参数cls是当前正在实例化的类。    如果要得到当前类的实例,应当在当前类中的 __new__() 方法语句中调用当前类的父类的 __new__() 方法    例如,如果当前类是直接继承自 object,那当前类的 __new__() 方法返回的对象应该为:    def __new__(cls, *args, **kwargs):        ...        return object.__new__(cls)如下面的例子:
看完下面几个例子尝试自己动手写几个关于new魔法的使用方法
class CapStr(str):
    "小写转换大写"
    def __new__(cls,string):
        string = string.upper()
        return str.__new__(cls,string)

class C2F(float):
    "摄氏度转换为华氏度"
    def __new__(cls, arg=0.0):
        return float.__new__(cls, arg * 1.8 + 32)

class Nint(int):
    "传入的参数是字符串的时候,返回该字符串中所有字符的 ASCII 码的和(使用 ord() 获得一个字符的 ASCII 码值)"
    def __new__(cls, arg=0):
        if isinstance(arg, str):
            total = 0
            for each in arg:
                total += ord(each)
            arg = total
        return int.__new__(cls, arg)

class PositiveInteger(int):
    "永远都是正数的整数类型"
    def __new__(cls, value):
        return int.__new__(cls, abs(value))
__init__(self,[...])   类的初始化方法。它获取任何传给构造器的参数(比如我们调用 tt = Test(100,200) ,__init__ 就会接到参数 100 和 200 。 __init__ 在Python的类定义中用的最多。举例:看完自己尝试些几个关于init魔法方法的使用
class Test():
    """
    用于初始化类
    """
    def __init__(self, a, b):
        self.a = a
        self.b = b

    def res(self):
        return (self.a, self.b)

class Rect:
    "矩形类,长宽,求面积与周长"
    def __init__(self,x,y):
        self.x = x
        self.y = y

    def getPeri(self):
        return (self.x + self.y) * 2

    def getArea(self):
        return self.x * self.y
#你可能在想什么会需要用到这个__init呢?#比如上面这个矩形类,因为你需要知道它的长和宽,才能求周长与面积#打个比方,假如你要构造一个圆类,椭圆类呢?是不是需要定义一些必要参数,才能求出他的面积或者周长。

原文地址:https://www.cnblogs.com/Stubbon/p/10225927.html

时间: 2024-10-12 11:45:25

魔方方法篇第一章--------构造与析构的相关文章

深度探索C++对象模型 第五章 构造、析构、拷贝语意学

1. const 成员函数需要吗? 尽量不要,如果存在继承,则无法预支子类是否有可能改变data member 2. pure virtual constructor 可以实现类的隐藏吗(包含data member)?   这样子类无法调用base 的构造函数对数据初始化,所以可以用protected来实现构造函数,可以实现子类调用: 3. 如果class中存在virtual function,则编译器会再构造函数中对vptr进行初始化(在base构造函数调用之后,而代码实现之前) 4.拷贝构造

《白帽子讲Web安全》——第一篇 第一章 我的安全世界观

前些日子定的书单,下放给各淘宝卖家,今天来的第一本就是这本,是一个我完全陌生的领域,然而强烈的好奇心,催使我看完了第一章,其实就是个概述. 1.1 Web安全简史 exploit:黑客们使用的漏洞利用代码. Script Kids:只对攻击本身感兴趣,没有动手能力,对计算机原理和各种编程技术略知一二,因而只能编译别人的代码的黑客,即“脚本小子”. 1. Web安全的兴起 (1)SQL注入 (2)XSS (3)CSRF http://blog.csdn.net/dyllove98/article/

第一部分 基础篇 第一章 走进MongoDB

声明:该文章主要来自<MongoDB实战>一书内容,主要想通过该书学习MongoDB的相应知识,加深理解,故写在自己的博文当中,作为记录在最后的章节中,会有一个自己集合MongoDB数据库应用的JavaEE的web应用. 第一章 走进MongoDB MongoDB是一个高性能.开源.无模式的文档型数据库,是当前NoSQL数据库产品中最热门的一种,它在许多场景下可用于替代关系型数据库或者键/值存储方式,MongoDB使用C++开发,MongoDB的官网是地址是:http://www.mongod

Java语言程序设计(基础篇)第一章

第一章 计算机.程序和Java概述 1.1引言 什么是程序设计呢? 程序设计就是创建(或者开发)软件,软件也称为程序. 1.2什么是计算机 计算机是存储和处理数据的电子设备,计算机包括硬件(hardware)和软件(software)两部分.

魔方方法之--类的构造(__init__,__new__)和析构(__del__)方法

构造方法(参见小甲鱼入门教程) __ init__()方法:类的初始化方法,初始化类对象时被调用,需要的时候再调用它 注意点:这个方法的返回值必须是None class Rectangle(): def __init__(self,width,height): self.width =width self.height=height __ new __ ()方法:实际调调用在__ init __()之前.实例化对象时第一个被调用的方法.在新创建一个对象时调用,一般不会重写它,继承自不可变类型,才

SICP 第一章 构造过程抽象 1

Chapter 1 Building Abstractions with Procedures .title { text-align: center } .todo { font-family: monospace; color: red } .done { color: green } .tag { background-color: #eee; font-family: monospace; padding: 2px; font-size: 80%; font-weight: normal

IOS开发之网络篇第一章:数据交换格式

网络通信最常用的数据通信格式是xml和Json,各有各的好处,不管怎样,这种的格式,我们在开发的过程中经常使用的,现在就这两种格式进行记录笔记,以下内容不做详细分析,只针对如何应用各种读写工具进行对xml和json内容的操作 xml 解析XML文件现在有两种主流的,SAX和DOM SAX-基于时间事件驱动,意思就是读取的过程中,是由上往下的读取xml文件,当遇到节点的时候,触发相应的事件,使用上比较快,缺点是不能修改文件内容 DOM-以树状形式加载,加载后存放在内存当中,所以如果文件大,读取的时

发音篇--第一章

KK音标分为:母音和子音. 母音可以单独存在,但是子音 必须与母音在一起才能用来发音. 母音:分为 两个发轻声的音 和 剩下的发四声的音.  两个发轻声的音类似中文的轻声,发音短促,顿一下. 且这两个轻声的音节必须在非重音节中 如果要放在重音节中,就必须变换成其他的音节:如下图: 母音:从左到右,从上到下 第一个母音:嘴角向两边阔,舌头用力 第二个母音:嘴巴稍收拢 (英文中,同类的事物在一起时,前面的发音向上扬,最后一个发音向下压,所以英文的26个字母有两种念法) 第三个母音:

数理统计总结篇第一章

部分知识忽略------只列举重点部分. 古典概型和几何概型见高中课本概率知识. -----------------------------------------(分割线) 概率加法公式:(广义加法公式) P(A+B)=P(A)+P(B)-P(AB) 加一例题: 设P(A)=0.6,P(B)=0.7,P(AB)=0.4,试求:P(A+B),P(AB非),P(A非B),P(A非B非). 解:运用公式,P(A+B)=P(A)+P(B)-P(AB)=0.6+0.7-0.4=0.9; P(AB非)=P