先划一下重点:

  • 6个魔法方法;
  • 动态操作属性的4个函数;

魔法方法

魔法方法的简单介绍

  • 魔法方法的命名规则:方法名(前后各有2个下划线)。

  • 通常情况下,不会主动去调用魔法方法,而是在满足一定的条件下,会自动去调用魔法方法。

  • 常用的魔法方法有6个,分别是:new、del、str、repr、bytes、call,下面我为大家一一讲解。

new方法

  • 注意1 :在创建对象的时候,会首先调用该方法,init方法还是在 new方法之后被调用;
  • 注意2 :一个不需要@classmethod修饰的类方法;
  • 注意3 :我们只需要知道,在创建对象的时候,new方法比init方法,先调用即可。平时没怎么用它;
class Person:
# __new__不用@classmethod修饰的一个类方法
# 在创建对象的时候,会首先调用该方法
# 如果在该方法中,返回当前类的对象(也即创建对象),接下来会调用__init__方法,对对象进行初始化。否则,__init__方法不会得到执行
def __new__(cls):
return super().__new__(cls) # 这行代码是创建对象,只是我现在不太明白 Person() # 在我们写类的时候,不需要写这个。这里讲述一下,只是想让我们知道。在创建对象的时候,__new__方法比__init__方法,先调用

若一个类中既有new方法,也有init方法,当我们创建对象时候,首先执行new方法。

假如,new方法中没有return super().new(cls) ,则不会执行init方法。写上以后,表示再次创建一个对象才会执行init方法。

# 第一段代码
class Person:
def __new__(cls):
print("__new__执行")
return super().__new__(cls) # 这行代码是创建对象,只是我现在不太明白 def __init__(self):
print("__init__执行") p = Person() # 第二段代码
class Person:
def __new__(cls):
print("__new__执行")
# return super().__new__(cls) # 假如不返回,当前类的对象,__init__就不会执行 def __init__(self):
print("__init__执行") p = Person() # 因为,这里创建的对象,先去执行new方法了

结果如下:

del方法

在销毁对象的时候(对象指的是我们自己创建的对象),会首先调用该方法。

class Person:
def __init__(self):
print("__init__执行")
# 在该方法中,可以执行一些清理工作
def __del__(self):
print("该对象已经被销毁") p = Person() # 可以看出,因为没有对象销毁,所以不会调用该方法

结果如下:

class Person:
def __init__(self):
print("__init__执行")
def __del__(self):
print("该对象已经被销毁")
p = Person()
del p

结果如下:

str方法

  • 注意1 :该方法在使用内建函数(str,format,print)的时候,会自动调用;
  • 注意2 :该方法末尾,需要返回一个str类型的对象;
class Person:
def __new__(cls):
print("__new__执行")
return super().__new__(cls)
def __init__(self):
print("__init__执行")
def __del__(self):
print("该对象已经被销毁")
# 在使用内建函数(str,format,print)的时候,会自动调用该方法
# 该方法需要返回一个str类型的对象
# def __str__(self):
# return "Person类型的对象"
p = Person()
print(p)

结果如下:

class Person:
def __new__(cls):
print("__new__执行")
return super().__new__(cls)
def __init__(self):
print("__init__执行")
# 在使用内建函数(str,format,print)的时候,会自动调用该方法
# 该方法需要返回一个str类型的对象
def __str__(self):
return "Person类型的对象" p = Person()
p

结果如下:

class Person:
def __new__(cls):
print("__new__执行")
return super().__new__(cls)
def __init__(self):
print("__init__执行")
# 在使用内建函数(str,format,print)的时候,会自动调用该方法
# 该方法需要返回一个str类型的对象
def __str__(self):
return "Person类型的对象" p = Person()
print(p)

结果如下:

repr方法

  • 注意1 :该方法在使用内建函数(repr)的时候,会自动调用;
  • 注意2 :该方法也需要返回一个str类型的对象;
class Person:
def __new__(cls):
print("__new__执行")
return super().__new__(cls)
def __init__(self):
print("__init__执行")
def __del__(self):
print("该对象已经被销毁")
def __str__(self):
return "Person类型的对象"
# __str__ 与 __repr__ 的区别:二者都是返回对象的字符串表示。
# 不同的是:__str__ 返回的通常是让人容易阅读的格式。__repr__返回的是面向Python解释器的,通常格式:<内容>
def __repr__(self):
return "<Person class>" p = Person()
print(str("abc")) # 结果是abc,这个更加接近人阅读模式
print(repr("abc")) # 结果是'abc',字符串本来就是带引号的,所以这个和python解释器更相近

结果如下:

bytes方法

该方法在使用内建函数(bytes)的时候,会自动调用.

class Person:
def __new__(cls):
print("__new__执行")
return super().__new__(cls)
def __init__(self):
print("__init__执行")
def __del__(self):
print("该对象已经被销毁")
def __str__(self):
return "Person类型的对象"
def __repr__(self):
return "<Person class>"
def __bytes__(self):
return b"byte person class" p = Person()
print(bytes(p))

结果如下:

call方法

把对象当成函数来使用的时候,会自动调用。

class Person:
def __new__(cls):
print("__new__执行")
return super().__new__(cls)
def __init__(self):
print("__init__执行")
def __del__(self):
print("该对象已经被销毁")
def __str__(self):
return "Person类型的对象"
def __repr__(self):
return "<Person class>"
def __bytes__(self):
return b"byte person class"
# 把对象当成函数来使用的时候,会自动调用该方法
def __call__(self):
print("把对象当成函数来使用的时候") p = Person()
p()

结果如下:

动态操作属性的4个函数

这4个函数分别是:hasattr、getattr、delattr、setattr,下面我们一一来讲述。

hasattr(参数1,参数2)

  • 第一个参数 :对象;
  • 第二个参数 :属性名;
  • 含义:判断某个对象,是否存在指定的属性名。如果存在,返回True,否则,返回False;
class Person():
pass p = Person()
print(hasattr(p,"name"))
p.name = "3417"
print(hasattr(p,"name"))

结果如下:

getattr(参数1,参数2,参数3)

  • 第一个参数 :对象;
  • 第二个参数 :属性名;
  • 第三个参数 :当属性不存在时,返回默认值,这个默认值也是自己设置;
  • 含义:返回对象对应的属性(第二个参数指定的属性)。传入2个参数,若不存在,则报错;穿入3个参数,若不存在,返回第三个参数设置的默认值;
class Person():
pass p = Person()
print(getattr(p, "name"))

结果如下:

class Person():
pass p = Person()
p.name = "关注一波?"
print(getattr(p, "name"))

结果如下:

class Person():
pass p = Person()
print(getattr(p,"age","没有属性返回的默认值"))

结果如下:

setattr(参数1,参数2,参数3)

  • 第一个参数:对象;
  • 第二个参数:属性名;
  • 第三个参数:属性值;
  • setattr(p,"age",20) 相当于 p.age = 20;
class Person():
pass p = Person()
setattr(p,"age",20)
print(p.age)

结果如下:

delattr(参数1,参数2,参数3)

  • 第一个参数:对象;
  • 第二个参数:属性名;
  • delattr(p,"name") 相当于 del p.name;
class Person():
pass p = Person()
setattr(p,"age",20)
delattr(p,"age")
print(hasattr(p,"age"))

结果如下:

注意1 :动态操作属性没有直接操作属性简便,但是比直接访问属性灵活。

注意2 :直接访问属性必须在写代码时,就需要知道属性的名字,而动态操作属性没有此限制(这在其他语言中叫做'"反射")。

class Person():
pass p = Person()
unknown = input("请输入属性名:")
value = input("请输入属性值:")
setattr(p, unknown, value)
print(getattr(p, unknown))

结果如下:

Python基础(二十一):面向对象“类”第四课——魔法方法的更多相关文章

  1. 洗礼灵魂,修炼python(39)--面向对象编程(9)—魔法方法表

    好的,不多说,大招来了,几乎完整的魔法方法: 基本的魔法方法 Normal 0 7.8 磅 0 2 false false false EN-US ZH-CN X-NONE /* Style Defi ...

  2. Bootstrap <基础二十一>徽章(Badges)

    Bootstrap 徽章(Badges).徽章与标签相似,主要的区别在于徽章的边角更加圆滑. 徽章(Badges)主要用于突出显示新的或未读的项.如需使用徽章,只需要把 <span class= ...

  3. python基础——实例属性和类属性

    python基础——实例属性和类属性 由于Python是动态语言,根据类创建的实例可以任意绑定属性. 给实例绑定属性的方法是通过实例变量,或者通过self变量: class Student(objec ...

  4. Python 基础 二

    Python 基础 二 今天对昨天学习的Python基础知识进行总结,学而不思则惘,思而不学则殆! 一.先对昨天学习的三大循环的使用情况进行总结: 1.while循环的本质就是让计算机在满足某一条件的 ...

  5. php面向对象类中常用的魔术方法

    php面向对象类中常用的魔术方法   1.__construct():构造方法,当类被实例化new $class时被自动调用的方法,在类的继承中可以继承与覆盖该方法,例: //__construct( ...

  6. Python类属性访问的魔法方法

    Python类属性访问的魔法方法: 1. __getattr__(self, name)- 定义当用户试图获取一个不存在的属性时的行为 2. __getattribute__(self, name)- ...

  7. python基础-9.1 面向对象进阶 super 类对象成员 类属性 私有属性 查找源码类对象步骤 类特殊成员 isinstance issubclass 异常处理

    上一篇文章介绍了面向对象基本知识: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用(可以讲多函数中公用的变量封装到对象中) 对象 ...

  8. python基础学习Day17 面向对象的三大特性之继承、类与对象名称空间小试

    一.课前回顾 类:具有相同属性和方法的一类事物 实例化:类名() 过程: 开辟了一块内存空间 执行init方法 封装属性 自动的把self返回给实例化对象的地方 对象:实例 一个实实在在存在的实体 组 ...

  9. python基础学习Day15 面向对象、类名称空间、对象名称空间 (2)

    一.类 先看一段代码: class Person: animal = '高级动物' walk_way = '直立行走' # 静态属性,静态变量,静态字段 language = '语言' def __i ...

随机推荐

  1. C++算法代码——和为给定数

    题目来自:http://218.5.5.242:9018/JudgeOnline/problem.php?cid=1376&pid=0 题目描述 给出若干个整数,询问其中是否有一对数的和等于给 ...

  2. sublime 使用过程中遇到的问题

    1.当我把鼠标放置在下图所示的class上几秒钟后,sublime就会在全局查找当前的class字符,这时sublime就会出现卡顿或无响应 解决方法: 点击preferences下的settings ...

  3. 4. Vue基本指令

    目录 1. v-on指令 2. v-if指令 3. v-show指令 4. v-for指令 5. v-model指令 一. v-on指令 1. 基础用法 v-on是事件监听的指令, 下面来看简单用法 ...

  4. 数据处理_HIVE增量ETL的一种方式

    适用场景: 贴源层主表历史数据过大,ETL不涉及历史数据对比或聚合 处理流程: 1.确定一个业务主键字段或物理主键字段 2.确定一个可以判断增量数据范围的字段,这取决于具体的业务场景,一般选用记录的创 ...

  5. 5. vue常用高阶函数及综合案例

    一. 常用的数组的高阶函数 假设, 现在有一个数组, 我们要对数组做如下一些列操作 1. 找出小于100的数字: 2. 将小于100的数字, 全部乘以2: 3. 在2的基础上, 对所有数求和: 通常我 ...

  6. iframe页面刷新

    //方法1 document.getElementById('FrameID').contentWindow.location.reload(true); //方法2 document.getElem ...

  7. 第46天学习打卡(四大函数式接口 Stream流式计算 ForkJoin 异步回调 JMM Volatile)

    小结与扩展 池的最大的大小如何去设置! 了解:IO密集型,CPU密集型:(调优)  //1.CPU密集型 几核就是几个线程 可以保持效率最高 //2.IO密集型判断你的程序中十分耗IO的线程,只要大于 ...

  8. 一文读懂clickhouse集群监控

    更多精彩内容,请关注微信公众号:后端技术小屋 一文读懂clickhouse集群监控 常言道,兵马未至,粮草先行,在clickhouse上生产环境之前,我们就得制定好相关的监控方案,包括metric采集 ...

  9. android上实现0.5px线条

    转: android上实现0.5px线条 由于安卓手机无法识别border: 0.5px,因此我们要用0.5px的话必须要借助css3中的-webkit-transform:scale缩放来实现. 原 ...

  10. 剑指 Offer 39. 数组中出现次数超过一半的数字 + 摩尔投票法

    剑指 Offer 39. 数组中出现次数超过一半的数字 Offer_39 题目描述 方法一:使用map存储数字出现的次数 public class Offer_39 { public int majo ...