python3基础知识复习 -- 魔法方法之构造,算数,属性定义

Python复习 Python复习1 注释 注释分为两种单行注释和多行注释。单行注释用#,多行用三个单引号(’’’ ‘’’)或三个双引号(""" “”") #我是单行注释 ‘’‘我是单引号,多行注释’’’ “”“我是双引号,多行注释 “”” 变量 变量的类型有Numbers(数字)类型,布尔类型,String(字符串)类型,List(列表)类型,Tuple(元组)类型,Dictionary(字典)类型 变量名不可以... 阅读详情

魔法方法: 构造和析构

  1. __init__(self[,…]) — 返回值一定是none.
 class A:
 	def __init__(self):
 	return 2022
 
 a2 = A()
 Traceback (most recent call last):
 File "\<pyshell#64>", line 1, in \<module>
 a2 = A()
 TypeError: __init__() should return None, not 'int'
  1. __new__(cls[, …])— 实例化时真正第一个被调用的方法,它跟其他魔法方法不同,它的第一个参数不是 self 而是这个类(cls),而其他的参数会直接传递给 __init__ 方法的 一般不会去重写,只有在特殊的情况下,eg 继承了一个不可变的类,但是又需要做出修改时. __new__ 方法主要任务时返回一个实例对象.

    	a.>>> class CapStr(str):
    		def __new__(cls, string):
    			string = string.upper() #将调用字符串的upper()方法并赋给string
    			return str.__new__(cls, string)  #将新的string传给老的str的__new__方法,返回的对象给我们新的__new__()方法
    	
    		
    	>>> str1 = CapStr('i am just not capitalized!')
    	>>> str1
    	'I AM JUST NOT CAPITALIZED!'
    	
    	
    	b.''' Celsius to Fahrenheit '''
    	class C2F(float):
    	    def __new__(cls, arg=0.0):
    	       return float.__new__(cls, arg * 1.8 + 32) 
    	>>> print(C2F(32))
    	89.6
    	
    	c.定义一个类继承于 int 类型,并实现一个特殊功能:当传入的参数是字符串的时候,返回该字符串中所有字符的 ASCII 码的和(使用 ord() 获得一个字符的 ASCII 码值)。
    	class Nint(int):
            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)
    	
    	d. Word继承str但是可以比较输入单词的长度,重写运算,有空格时取空格前面的单词。
    	class Word(str):
    	    def __new__(cls,string):
    	        if ' ' in string:
    	            new_str = string[:string.index(' ')]   #切片得到前面的单词
    	            if new_str:
    	                prompt = 'The value contains spaces, truncating to first space!'
    	                string = new_str
    	                
    	            else:  #如果第一个单词前面有空格
    	                prompt = 'Oh my gosh, you have space in the front!'
    	
    	            print(prompt)
    	
    	        return str.__new__(cls, string) # if执行完成后,最后执行return
    
    
  2. __del__(self) — 垃圾回收机制使用, 当del删除实例对象时,如果这个对象的所有引用都被删除时就会被垃圾回收机制干掉,这个时候才会调用内置的__del__方法。__del__ 方法是当垃圾回收机制回收这个对象的时候调用的

    	>>> class C:
    		def __init__(self):
    			print('This is init method, I am called')
    		def __del__(self):
    			print('This is del method, I am called')
    	
    			
    	>>> c1 = C()
    	This is init method, I am called
    	>>> c2 = c1
    	>>> c3 = c2
    	>>> del c1
    	>>> del c2
    	>>> del c3 # 最后一个引用被删除时触发
    This is del method, I am called
    
  3. __str__() and __repr__()

    __str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,__repr__()是为调试服务的。

    解决办法是再定义一个__repr__()。但是通常__str__()__repr__()代码都是一样的,所以,有个偷懒的写法, 直接赋值如下。

    >>> class Student(object):
    ...     def __init__(self, name):
    ...         self.name = name
    ...     def __str__(self): # 重新定义__str__
    ...         return 'Student object (name: %s)' % self.name
    ...
    >>> print(Student('Michael'))  # 这样打印出来的实例,不但好看,而且容易看出实例内部重要的数据。
    Student object (name: Michael)
    
    
    >>> s = Student('Michael')
    >>> s
    <__main__.Student object at 0x109afb310>   # 直接打印出来的实例还是不好看
    
    
    # 重写__str__ 和 __repr__就好
    class Student(object):
        def __init__(self, name):
            self.name = name
        def __str__(self):
            return 'Student object (name=%s)' % self.name
        __repr__ = __str__  # 偷懒写法,定义好__str__()后直接赋值给__repr__()
    

魔法方法: 算数运算

类 - 属性和方法的封装

类型:整型,字符串,浮点型。。。

  • python 2.2 后作者对两者进行统一,将类型这些BIF函数变为工厂函数(实际是类对象,type(list)–> ‘class’ type)

  • 实际上对象是可以相加的(a, b 就是int的实例化对象)

a = int('123')
b = int('234')

a + b
357

1

  • 通过自定义下面的魔法方法可以自定义计算行为

  • 举例__add__ 和 __sub__方法,自己定义的时候注意无限递归的情形

    	>>> class New_int(int):
    			def __add__(self, other):        #自定义时改了规则
    				return int.__sub__(self, other) # 变成减法
    			def __sub__(self, other):
    				return int.__add__(self, other) # 变成加法
    		
    			
    		>>> a = New_int(3)
    		>>> b = New_int(6)
    		>>> a + b
    		-3
    		>>> a - b
    		9
    		
    	如果改成下面的形式
    		class New_int(int):
    			def __add__(self, other):
    				return self + other 
    			def __sub__(self, other):
    				return self + other
    		
    			
    		>>> a = New_int(3)
    		>>> b = New_int(6)
    		>>> a + b      # 当a调用add的时候返回的self就是a实例, other是b实例,所以self + other 还是a+b 这样又会去调用add方法导致无限递归
    		Traceback (most recent call last):
    		  File "<pyshell#23>", line 1, in <module>
    		    a + b
    		  File "<pyshell#20>", line 3, in __add__
    		    return self + other
    		  File "<pyshell#20>", line 3, in __add__
    		    return self + other
    		  File "<pyshell#20>", line 3, in __add__
    		    return self + other
    		  [Previous line repeated 1022 more times]
    		RecursionError: maximum recursion depth exceeded
    		
        # 加上int把对象变成数值就不会了
    		class New_int(int):
    			def __add__(self, other):
    				return int(self) + int(other) 
    			def __sub__(self, other):
    				return int(self) + int(other)
    		
    
  • Divmod() – 得到a//b的余数,eg 5//3 --> 2
    divmod(5, 3)

(1, 2)

​ Eg: 反运算 radd 重写 ---- 注意参数的顺序

	>>> a = Nint(3)
	>>> b = Nint(5)
	>>> a + b
	8
	>>> 1 + b
	6
	
    class Nint(int):
		def __radd__(self, other):
			return int.__sub__(self, other)
	
		
	>>> a = Nint(3)
	>>> b = Nint(5)
	>>> a + b
	8
	>>> 1 + b  # 当前面没有__add__方法时会调用后面的b的__radd__方法进行运算,由于这里我们重写了__radd__, 在这种情况下 int__sub__(self, other) 中self ==b, other == 1, 所以结果是5-1==4
	4

魔法方法: 属性访问

  • getattr(func, ‘str’, ‘default_message’)
  • property — 通过属性设置属性
  • 魔法方法控制属性访问
    • __getattr__(self, name) – 定义当用户试图获取一个不存在的属性时的行为
    • __getattribute__(self, name) – 定义当该类的属性被访问时的行为
    • __setattr__(self, name, value) – 定义当一个属性被设置时的行为
    • __delattr__(self, name) – 定义当一个属性被删除时的行为
      行为:首先会访问__getattribute__,如果在属性字典找不到的话就调用__getattr__
	class D:
		def __getattr__(self, name):
			print('getattr')
		def __getattribute__(self, name):
			print('getattribute')
			return super().__getattribute__(name)
		def __setattr__(self, name, value):
			print('setattr')
			super().__setattr__(name, value)
		def __delattr__(self,name):
			print('delattr')
			super().__delattr__(name)
			 
					 
	>>> d1 = D()
	>>> d1.size
	getattribute
	getattr
	>>> d1.size = 10
	setattr
	>>> d1.size
	getattribute
	10
	>>> del d1.size
	delattr
	>>> d1.size
	getattribute
	getattr

在这里插入图片描述

	class Rectangle:
	    def __init__(self, width, height):
	        self.width = width
	        self.height = height
	 
	    def __setattr__(self, name, value):
	        if name == "square":
	            self.width = value
	            self.height = value
	        else:
	            (x)self.name = value  ==>super().__setattr__(name, value) (最优解,使用基类的魔法方法)
                or 
				(x)self.name = value  ==>self.__dict__[name] =  value (使用字典中的属性赋值)
	# self.name = value 会造成死循环recursion, 在__init__初始化的时候会调用setattr,但是else的语句会继续做赋值运算然后又调用setattr
	 
	    def getArea(self):
	        return self.width * self.height

continue…

Python_类的调用的问题 | __init__() should return None, not ‘xxx‘ 这样写也会返回none 尽管 在go()里面有返回值 但在 go_1()中并没有return接受来自hello.go() 的返回值。python先调用了hello.go()函数打印了‘66’ ,然后打印go_1()但是其没有print也没有return ,所以第二个返回为none。如果直接打印go_1函数,则把该函数的内存地址打印出来,这显然不是我们想要的。可以调用其他类的构造方法或者直接返回别的实例对象来作为本类的实例,如果。2. 它的第一个参数是这个类,其他的参数是用来直接传递给。 阅读详情

相关推荐

Python类初始化方法__init__只能返回None

class Test: def __init__(self): self.x = 0 self.y = 0 return 0

Debug yourself! 1938

python新式类中的__new__方法与__init__方法

1.旧式类 在讲新式类之前,先看看旧式类是怎么用的。 class OldClass: pass OldClass() 上面就是旧式类的写法,默认继承type类。 2.新式类 python2中,如果定义一个新式类 class NewClass(object): pass 而在python3中,所有的类,均默认继承object,所以括号里也可以不显示指定object。 3.__new__方法与__init__方法 如果我们再IDE里面输入__new__字样,IDE会自动给我们补全方法如下:

bitcarmanlee的博客 1575

小甲鱼零基础python 笔记之 构造和析构(P42)

魔法方法: 构造和析构

peanutfish的专栏 600

Python_类的调用的若干问题和__init__() should return None, not 'xxx'

首先看一段代码: class hello(): def go(): a='66' print(a) def go_1(): hello.go() print(go_1) <function go at 0x000001A96EC62EA0> 如果直接打印go_1函数,则把该函数的内存地址打印出来,这显然不是我们想要的 改成print(...

Liubingzhe 1万+

[python复习8]魔法方法

魔法方法: 在Python中以两个下划线开头的方法,__init__、__str__、__doc__、__new__等,被称为"魔术方法"(Magic methods)。魔术方法在类或对象的某些事件出发后会自动执行,如果希望根据自己的程序定制自己特殊功能的类,那么就需要对这些方法进行重写。   注意:Python 将所有以 __(两个下划线)开头的类方法保留为魔术方法。所以在定义类方法时,除了上述魔术方法,建议不要以 __ 为前缀。 基本的魔法方法 __new__(cls[, ...]) 1. __n

weixin_45715405的博客 188

python复习41~42魔方方法

魔方方法: 构造与析构: 一:构造器 __new__(cls[,...]) 当继承一个不可变类型,有需要修改时,可以用此方法进行重写 主要作用是在一个对象实例化时返回一个实例对象,通常是参数cls这个类的实例化对象,到如也可以返回其它对象。 >>> class Capstr(str): def __new__(cls,string): string = string.upper() return str.__new__(cls,string) >>> a

m0_48840636的博客 233

Python复习笔记———超详细

Python复习笔记总结概括 一、前言 这是哪托针对老师的课件整理的复习笔记,基础入门,希望能对广大基础小白受用。内容如有错误的地方,麻烦指正。 笔记所有代码使用Microsoft VS Code的 Python、Jupyter 插件编程 二、语言基础 2.1标识符 1.2.1标识符 标识符可以包括英文、数字以及下划线,并且: ​ 开头必须是字母或下划线; ​ 不能以数字开头开头; ​ 区分大小写的; ​ 不能出现分隔符、标点符号或者运算符; ​ 不能使用关键字:def if for while cla..

qq_45824141的博客 4万+

python基础总复习

单引号或双引号新知识点:三引号定义字符串(支持换行)关关雎鸠,在河之洲,窈窕淑女,君子好逑。'''列表名称 = [元素值1, 元素值2, 元素值3]​# list列表类型支持直接打印# 打印列表的数据类型所以其方法主要是查询方法编号函数作用1元组[索引]根据==索引下标==查找元素2len()统计元组中数据的个数列表、元组的时候还给大家做过一个扩展:如何开发一个点名程序字典变量 = {}或字典变量 = dict()​。

qq_55451220的博客 2794

Python基础知识总结(期末小复习

文章目录 前言 复习要点 组合数据类型 序列类型通用操作符和函数 集合类型 映射类型 数值操作 运算符 字符串操作 字符串切片 基本切片操作 高级切片操作 操作、相关函数、相关使用方法 字符串格式化(不需要花费太多时间) format{}格式化 %格式化 列表 一些要注意的地方 列表推导式:(有能力就掌握一下) 字典 一些要注意的地方 统计出现次数并从大到小

qq_41758898的博客 1894

python期末复习----

注意:本文仅仅是自己复习所用,只包含我所需要熟悉的知识点。

2401_83411974的博客 722

技术岗面试基础知识复习——python3

多线程

qq_36718816的博客 565

python复习

python复习 文章目录python复习一、Python基础笔试题1、什么是变量?2、 python和CPython是什么关系?3、 如何生成一个整数序列?4、表达式与语句的主要区别是什么?5、 Python的基础数据类型有哪些?6、在Python中如何进行代码缩进?如何进行代码缩进?7、如何输出Python中的所有关键字?8、Python交互模式的主要用途有哪些?9、python中的控制结构有哪些?10、什么是三元表达式?11、循环结构中的else语句是多余的吗?12、break与continue的区别

weixin_47774641的博客 951

Python期末复习大纲

Python 程序设计课程,期末复习应重点覆盖基础语法、常用数据结构和算法,以及常见的编程技巧和调试方法。

小火龙的博客 1318

python期末复习笔记

局部变量和全局变量无关,当在函数内定义一个和全局变量同名的变量时,不会对全局变量的值进行修改,而是相当于定义一个新的变量,此新变量在函数体结束后也会销毁。A.y(self)#方法一,通过父类名调用父类的成员方法时,要加参数self。* 通过下标删除`del 列表名.下标`无返回值`列表名.pop(下标)`返回值为被删除的元素值。super().y()#方法二,通过super调用,不用加参数self。print(str(stu))#Student类对象,name:AAA,age:31。

GengShuhan_的博客 271

Python基础知识点——期末复习

1.基本数据类型 1.1数字 1.2字符串 1.3布尔类型 1.4输入与输出 2.运算符 3.列表与元组 3.1基本操作 3.2列表 3.3元组 4.字典与集合 5.字符串 6.函数 7.模块 8.异常处理 9.文件及目录操作 1.基本数据类型 1.1数字 python中的整数(int),浮点数(float),复数(complex) 整数(int):整数是不带有小数部分的数字,包括...

maybepeople的博客 8221

Python高阶

尽量精简的阐明问题

qq_62260432的博客 411

python基础语法复习

本文为学习深度学习前熟悉回顾python语法的准备工作,主要学习网站为python菜鸟,本文主要内容为一些最基础或容易混淆的基础知识与基本语法框架,仅供快速查阅,具体详细内容可在每部分链接直接跳转。

Astro_1999的博客 1305
上一篇: python3基础知识复习 -- 面向对象编程多态,BIF,修饰符
下一篇: python3基础知识复习 -- 魔法方法之描述符,定制序列,迭代器
peanutfish
博客等级 码龄14年 255粉丝 152原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值