目录

特殊属性

__dict__查看属性和方法

__class__查看对象所属类

__bases__查看子类的父类

__mro__查看类的层次结构

__subclasses__查看父类被继承的子类

特殊方法

__add__()类的对象相加

__len__()类的对象的长度

__new__()和__init__()


前面分享完了面对对象的三大特征:封装继承多态之后,我们再来看一下特殊属性和特殊方法

  名称 描述
特殊属性 __dict__ 获得类对象或实例对象所绑定的所有属性和方法的字典
特殊方法 __len__() 通过重写__len__()方法,让内置函数len()的参数可以是自定义类型
__add__() 通过重写__add__()方法,可使用自定义对象具有“+”功能
__new__() 用于创建对象
__init__() 对创建对象进行初始化

所谓的特殊属性和特殊方法就是两个下划线开始,两个下划线结束的属性和方法,现在来看看他们有什么作用

特殊属性

__dict__查看属性和方法

class A:
pass class B:
pass # 多继承
class C(A, B):
def __init__(self, name, age):
self.name = name
self.age = age # 创建C类的对象
x = C('SWS', 20) # x是C类的实例对象
print(x.__dict__)

我们这里有两个A,B类,然后C类多继承了他们,关于多继承可以看看python之继承及其实现方法,然后就定义了一个__init__()初始化的方法并且定义了两个实例属性name和age,那我们现在就可以用__dict__来查看我们的C类对象x的所有属性和方法

{'name': 'SWS', 'age': 20}

那我们再来看看C类的属性和方法

# 创建C类的对象
x = C('SWS', 20) # x是C类的实例对象
print(x.__dict__) # 实例对象的属性字典
print(C.__dict__) #类对象的属性字典
{'name': 'SWS', 'age': 20}
{'__module__': '__main__', '__init__': <function C.__init__ at 0x000001F3AB41FB80>, '__doc__': None}

那我们现在就可以看到C类的属性'__module__': '__main__'之后就接了'__init__'方法

__class__查看对象所属类

我们用__dict__可以查看属性和方法,当然还可以查看对象所属的类是什么啦

print(x.__class__)
<class '__main__.C'>

我们现在就可以看到x对象所属的类是C类

__bases__查看子类的父类

现在由对象可以看到类,那么由子类可不可以看到父类呢,答案当然是可以的啦,不过这事就要用到__bases__啦

print(C.__bases__)
(<class '__main__.A'>, <class '__main__.B'>)

这样我们就可以看到C类的父类类型的元素A,B啦

__mro__查看类的层次结构

那我们现在可以查看子类的父类了,但是又觉得一层一层看太麻烦了怎么办,那这个时候我们就可以查看层次结构来一目了然

print(C.__mro__)
(<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)

现在是不是觉得看过去一目了然,很方便了呢

__subclasses__查看父类被继承的子类

现在有人不高兴了说,凭什么可以子类查看父类,不可以父类查看子类呢,哈哈哈,不要着急,这不就来了吗

class C(A, B):
def __init__(self, name, age):
self.name = name
self.age = age class D(A):
pass print(A.__subclasses__())

为了更直观一点,我有添加了一个子类来继承A类,哈哈哈

[<class '__main__.C'>, <class '__main__.D'>]

看看看,输出了子类的列表了吧,哈哈哈,一点也米有不公平呀

特殊方法

分享完了特殊属性,终于到特殊方法啦

__add__()类的对象相加

我们知道python中整数类型的对象可以相加,虽然是通过+来完成的,但是底层是调用__add__()方法来完成的

a = 60
b = 300
c = a + b
d = a.__add__(b)
print(c, d)
360 360

那我们自定义类型的对象可不可以呢,一起来看看吧

class SWS:
def __init__(self, name):
self.name = name sws_1 = SWS('慢蜗牛')
sws_2 = SWS('小蜗牛')
sws_3 = sws_2 + sws_1 print(sws_3)

我们来看看两个对象是不是可以相加,结果大家应该已经猜到了吧

Traceback (most recent call last):
File "D:\pythonProject\main.py", line 8, in <module>
sws_3 = sws_2 + sws_1
TypeError: unsupported operand type(s) for +: 'SWS' and 'SWS'

哎呀,电脑报错啦,告诉我们SWS和SWS不能进行相加,那慢蜗牛的牛脾气上来了,我还非要你们想加,哼哼哼

class SWS:
def __init__(self, name):
self.name = name def __add__(self, other): # 可以看到这里运用了__add__()方法
return self.name + other.name sws_1 = SWS('慢蜗牛')
sws_2 = SWS('小蜗牛')
sws_3 = sws_2 + sws_1 print(sws_3)

我们可以看到运用了__add__()方法,并且返回两个名字,来看看行不行

小蜗牛慢蜗牛

哎呀,我真是太牛批啦,这都完成了,那我们来看看直接用__add__()来相加

class SWS:
def __init__(self, name):
self.name = name # def __add__(self, other): # 这里是注释掉了的
# return self.name + other.name sws_1 = SWS('慢蜗牛')
sws_2 = SWS('小蜗牛')
sws_3 = sws_2.__add__(sws_1) print(sws_3)
Traceback (most recent call last):
File "D:\pythonProject\main.py", line 11, in <module>
sws_3 = sws_2.__add__(sws_1)
AttributeError: 'SWS' object has no attribute '__add__'

好吧好吧,现在看来,要想实现两个自定义类型对象的相加就必须用到被注释掉的部分啦

__len__()类的对象的长度

谈到__len__(),大家肯定就想到了对列表求长度的函数len(),那我们来看看这两者的功能

list_1 = [22, 44, 66, 88]
print(len(list_1))
print(list_1.__len__()) # 下面是输出
4
4

对于列表来说这两者功能都一致啊,那我们想要输出自定义类型对象的长度呢

print(len(sws_1))

# 下面是输出
Traceback (most recent call last):
File "D:\pythonProject\main.py", line 19, in <module>
print(len(sws_1))
TypeError: object of type 'SWS' has no len()

哎呀,又报错了,哈哈哈,牛脾气不改,接着和你刚

class SWS:
def __init__(self, name):
self.name = name def __add__(self, other):
return self.name + other.name def __len__(self):
return len(self.name) sws_1 = SWS('慢蜗牛')
sws_2 = SWS('SWS') print(len(sws_1))
print(len(sws_2)) # 下面是输出
3
3

没有错啊,这回你不刚了吧,电脑还是没有人聪明啊

__new__()和__init__()

class SWS(object):
def __new__(cls, *args, **kwargs):
print('__new__被调用执行了,cls的id为{}'.format(id(cls)))
obj = super().__new__(cls)
print('创建的对象的id为{}'.format(id(obj)))
return obj def __init__(self, name, age):
print('__init__被调用了,self的id为{}'.format(id(self)))
self.name = name
self.age = age print('object这个类对象的id为{}'.format(id(object)))
print('SWS这个类对象的id为{}'.format(id(SWS))) sws_1 = SWS('慢蜗牛', 20)
print('sws_1这个SWS类的实例对象的id为{}'.format(id(sws_1)))
object这个类对象的id为140735397846528
SWS这个类对象的id为1979325068288
__new__被调用执行了,cls的id为1979325068288
创建的对象的id为1979331727120
__init__被调用了,self的id为1979331727120
sws_1这个SWS类的实例对象的id为1979331727120

我们之前总是提到创建对象的初始化用__init__()来完成,可是初始化之前,我们肯定要创建一个新对象才行呀,那我们现在就来看看这两者的关系

我们先创建一个实例对象,用=来赋值肯定是从右边开始

然后看看我们cls的ID和类的ID是一样的,就可以知道第一步是把类赋给cls,然后cls就返回了一个新的对象给obj

第二步就是obj把自己赋给了self来初始化对象

最后返回初始化好的对象给sws_1

python之特殊属性和特殊方法的更多相关文章

  1. 【python学习笔记】9.魔法方法、属性和迭代器

    [python学习笔记]9.魔法方法.属性和迭代器 魔法方法:xx, 收尾各有两个下划线的方法 __init__(self): 构造方法,创建对象时候自动执行,可以为其增加参数, 父类构造方法不会被自 ...

  2. python面向对象学习(三)私有属性和私有方法

    目录 1. 应用场景和定义方式 2. 伪私有属性和私有方法 在java或者其他的编程语言中,使用访问修饰符来限制属性和方法的访问级别,一般有public.protected.default.priva ...

  3. python私有属性和私有方法

    私有属性和私有方法 01. 应用场景及定义方式 应用场景 在实际开发中,对象 的 某些属性或方法 可能只希望 在对象的内部被使用,而 不希望在外部被访问到 私有属性 就是 对象 不希望公开的 属性 私 ...

  4. python中类中属性和方法的具体定义方法和使用

    1. Python中类中特性分成属性和方法 属性和方法都分为私有和公有的,私有的只可以在本类中使用外部是无法访问的 2. 定义属性(成员变量)的语法格式(公有属性/私有属性) class 类名: de ...

  5. python动态添加属性和方法

    ---恢复内容开始--- python动态添加属性: class Person(object): def __init__(self,newName,newAge): self.name = newN ...

  6. Python面向对象-类、实例的绑定属性、绑定方法和__slots__

    绑定属性 从之前的文章中,我们知道python是动态语言——实例可以绑定任意属性. 那如果实例绑定的属性和类的属性名一样的话,会是什么情况呢? >>> class Student(o ...

  7. Python面向对象之私有属性和私有方法

    01. 应用场景及定义方式 应用场景 在实际开发中,对象 的 某些属性或方法 可能只希望 在对象的内部被使用,而 不希望在外部被访问到 私有属性 就是 对象 不希望公开的 属性 私有方法 就是 对象  ...

  8. Python 类的私有属性与私有方法

    1.隐藏的使用场景 在Python类中,有些属性和方法只希望在对象的内部被使用,而不希望在外部被访问到, 2.定义方式, 在属性名或方法名前增加两个下划线,定义的就是私有属性或方法 #其实这仅仅这是一 ...

  9. Python笔记(二十六)_魔法方法_属性的魔法方法

    属性的魔法方法 __getattribute__(self,name):当该类的属性被访问时,自动触发,是最先被触发的属性方法 __setattr__(self,name,value):当一个属性被设 ...

  10. python中的魔术属性与魔法方法

    1.魔法属性 · 1.1__doc__魔法属性  表示类的描述信息 class Fo: """ 这是今天第一个魔术属性__doc__""" ...

随机推荐

  1. Centos安装 Apache Benchmark

    检查依赖包是否安装 1 rpm -qa|grep apr-util 2 3 rpm -qa|grep yum-utils 输出信息: 1 apr-util-1.5.2-6.el7.x86_64 2 y ...

  2. LaZagne:一键抓取目标机器上的所有明文密码的神器

    LaZagne 介绍 功能 LaZagne 是用于获取存储在本地计算机上的大量密码的开源应用程序. 每个软件都使用不同的技术(纯文本.API.自定义算法.数据库等)存储其密码.LaZagne 的作用就 ...

  3. java位运算及移位运算你还记得吗

    本文中所提到的运算都是基于整数来说的,因为只有整数(包括正数和负数)在操作系统中是以二进制的补码形式运算的,关于原码.反码.补码.位运算.移位运算的背景这里不再介绍,网上资料很多,感兴趣的可自行搜索. ...

  4. 论文解读(DWL)《Dynamic Weighted Learning for Unsupervised Domain Adaptation》

    [ Wechat:Y466551 | 付费咨询,非诚勿扰 ] 论文信息 论文标题:Dynamic Weighted Learning for Unsupervised Domain Adaptatio ...

  5. tcp3次握手

    tcp3次握手 1,三次握手流程图 2,三握手过程 当pc1想和pc2建立起连接时 pc1将连接信息写入报文 2.1,报文的序号(seq=x) 同步位(请求建立连接关系: SYN=1 ACK=0 控制 ...

  6. Rollup 编译资源离不开 plugin

    rollup 也是一个 JavaScript 的模块化编译工具,可以帮助我们处理资源. 与webpack比较 rollup相比 webpack 理念更为简单,能处理的场景也更有限. 资源类型 处理方式 ...

  7. 银河麒麟等 Linux系统 安装 .net 5,net 6及更高版本的方法

    最近项目上用到 银河麒麟的操作系统,需要搭建 .net 跨平台方案.一开始使用各种命令都安装不上,很多提示命令找不到,或者下载包时候网络无法下载. 网上教程很多,但没有一个是成功的,多数使用 apt ...

  8. 调研capacitor兼容openharmony平台可行性

    团队可能需要对开源的 capacitor 跨平台框架进行扩展,以生产支持 OpenHarmony 平台的应用,在此调研可行性.实现路径和预期工作量. 可行性分析 在验证 capacitor 是否可以将 ...

  9. el-date-picker 在表单中宽度(width)问题

    在使用element-plus的日期选择组件 el-date-picker的时候,发现form表单内的日期选择框并不能跟el-input 一样把宽度撑满.而是要小一圈. 这样在排版中显得不太整齐,但是 ...

  10. [ABC305C] Snuke the Cookie Picker题解

    题目大意 有一个 \(H\times W\) 的网格,一种有一个矩形,矩形中间有一个点被挖空,求这个点的坐标.(. 表示空白,# 表示矩形内的点) 解析 观察我们可以发现,每一矩形内的个点上下左右至少 ...