在 Python 3 中,object 类是 Python 为所有类所提供的父类(基类),因此所有的类都直接或者间接的继承了 object 类的属性和方法。
我们可以使用内置函数 dir() 去查看指定对象的所有属性和方法。
>>> class A:
... pass
...
>>> a = A()
>>> dir(a)
['__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__
hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '_
_repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']
>>> obj = object()
>>> dir(obj)
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__
init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '
__sizeof__', '__str__', '__subclasshook__']
>>>
![图片[1]-Python的object类(特殊属性、方法)以及新式类和经典类-尤尤'blog](https://pic.yxfseo.cn/wp-content/uploads/2023/01/2a1ff2425f155650.jpg?imageView2/0/interlace/1/q/75|imageslim)
在 Python 3 中,如果一个类没有写父类,则默认继承自 object 类。
特殊属性
__dict__ | 获得类对象或实例对象绑定的所有属性和方法的字典。 |
__class__ | 输出对象所属的类 |
__bases__ | 输出类的父类类型的元组 |
__base__ | 输出与类离得最近的基类 |
__mro__ | 输出类的层次结构 |
__subclasses__ | 输出子类列表 |
class A:
pass
class B:
pass
class C(A, B):
def __init__(self, name, age):
self.name = name
self.age = age
c = C('Tom', 10)
# 获得类对象或实例对象绑定的所有属性和方法的字典。
print(c.__dict__) # {'name': 'Tom', 'age': 10}
print(C.__dict__) # {'__module__': '__main__', '__init__': <function C.__init__ at 0x00000227583FF130>, '__doc__': None}
# 输出对象所属的类
print(c.__class__) # <class '__main__.C'>
# 输出父类类型的元组
print(C.__bases__) # (<class '__main__.A'>, <class '__main__.B'>)
# 输出和类离得最近的基类
print(C.__base__) # <class '__main__.A'>
# 查看类的层次结构:“类名.__mro__” 可以打印出当前类所继承的父类以及继承的层级关系。可以让我们快速得到类的继承关系。
print(C.__mro__) # (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class 'object'>)
# 输出子类列表
print(A.__subclasses__()) # [<class '__main__.C'>]
![图片[2]-Python的object类(特殊属性、方法)以及新式类和经典类-尤尤'blog](https://pic.yxfseo.cn/wp-content/uploads/2023/01/537395142a161815.jpg?imageView2/0/interlace/1/q/75|imageslim)
特殊方法
__len__() | 重写__len__()方法,让内置函数len()的参数可以是自定义类型。 |
__add__() | 重写__add__()方法,使得自定义对象具有“+”的功能。 |
__init__() | 创建对象时自动调用。 |
__new__() | 初始化方法。 |
1、__add__(self,other)
当我们将两个整数相加时,Python 解释器会在底层调用 __add__ 方法来完成相加操作。但是两个自定义对象不能进行相加操作。我们可以通过重写 __add__ 方法,使自定义对象具有 ‘+’ 功能。
a = 10
b = 100
print(a+b)
print(a.__add__(b))
class Student:
def __init__(self,name):
self.name = name
def __add__(self, other):
return self.name + other.name
stu1 = Student('汤姆')
stu2 = Student('杰克')
# 两个对象不能直接相加,如果要相加,需要重写__add__特殊方法
# s = stu1 + stu2 # TypeError: unsupported operand type(s) for +: 'Student' and 'Student'
s = stu1 + stu2
print(s) # 汤姆杰克
2、__len__()
通过重写 __len__() 方法,是内置函数 len() 的参数可以是自定义类型。
class Student:
def __init__(self, name):
self.name = name
def __len__(self):
return len(self.name)
stu1 = Student('汤姆')
lst = [10, 20, 30, 40]
print(len(lst)) # 内置函数len()
# 重写__len__()方法,才能将自定义对象当做参数传给len()内置函数
# print(len(stu1)) # TypeError: object of type 'Student' has no len()
print(len(stu1)) # 2
3、__new__()和__init__()
__new__用来创建对象,它是由object类提供的内置静态方法,所以在调用的时候要主动给 cls 传递参数。__init__()为实例属性初始化。
当使用 类名() 创建对象时,Python解释器会先自动调用__new__()方法为对象分配内存空间,然后返回对象的引用。Python解释器获得对象的引用后,将这个引用作为第一个参数传给__init__()方法。
注意:
重写__new__方法是为了对分配空间的方法进行改造,使得我们在使用类名()创建对象的时候,无论执行多少次,在内存中只会创建出一个实例对象,以达到单例设计模式(类创建的对象,在系统中只有唯一一个实例,也就是每次执行类名(),返回的对象地址都相同。例如音乐播放器,每次只能播放一首歌)
class Person(object):
def __new__(cls, *args, **kwargs): # 创建对象
print('__new__被调用执行了,cls的id值为{0}'.format(id(cls)))
obj = super().__new__(cls) # Person传给了object类,在object中创建一个对象obj
print('创建的对象的id值为{0}'.format(id(obj)))
return obj # 返回给self
def __init__(self,name,age): # 为创建的对象赋值
print('__init__被调用了,self 的id值为{0}'.format(id(self)))
self.name = name
self.age = age
print('object这个类对象的id为{0}'.format(id(object)))
print('Person这个类对象的id为{0}'.format(id(Person)))
print('-------------------------------------------------------------')
p1 = Person('张三',20) # 先执行赋值号右侧的代码,自动调用__new__,把Person传给了cls __init__初始化方法执行完成后,再把self赋值给p1
print('-------------------------------------------------------------')
print('p1这个Person的实例对象的id为{0}'.format(id(p1)))
![图片[3]-Python的object类(特殊属性、方法)以及新式类和经典类-尤尤'blog](https://pic.yxfseo.cn/wp-content/uploads/2022/11/fb9fa5f10c175801.jpg?imageView2/0/interlace/1/q/75|imageslim)
4、__str__()
object 类有一个方法 __str__(),用于返回一个对于对象的描述,在 ‘Python 类方法、静态方法和初始化方法’ 中有详细讲解。
我们使用 print 打印对象时,输出的是对象的内存地址。但我们可以通过重写 __str__() 方法来自定义这个输出内容,注意,__str__() 必须返回一个字符串。
class Student: # 默认继承自object
def __init__(self,name,age):
self.name = name
self.age = age
def __str__(self): # 重写__str__方法
return f'我叫{self.name},今年{self.age}岁。'
stu = Student('张三',21)
print(dir(stu))
# print(stu) # <__main__.Student object at 0x0000016DF4CB7430>
# 如果在类中重写了__str__方法,使用print打印对象输出的就是自定义的内容了
print(stu) # 自动调用__str__方法
![图片[4]-Python的object类(特殊属性、方法)以及新式类和经典类-尤尤'blog](https://pic.yxfseo.cn/wp-content/uploads/2022/11/25254b17dd170927.jpg?imageView2/0/interlace/1/q/75|imageslim)
新式类和旧式类(经典类)
新式类:以 object 为基类(父类)的类。
经典类:不以 object 为基类的类。
在 Python 2.x 中,如果没有指定父类,也不会把 object 作为基类。
而在 Python 3.x 中,如果未指定父类,则默认将 object 作为该类的基类,所以 Python 3.x 中定义的都是新式类。
注意:推荐使用新式类,在定义类的时候,如果没有父类,则让它继承自 object 基类。
class 类名(object):
pass
新式类和经典类在多继承中,会影响 MRO(方法搜索顺序)。
1 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
2 本站一律禁止以任何方式发布或转载任何违法的相关信息,访客发现请向站长举报。
3 本站资源大多存储在云盘,如发现链接失效,请联系我们我们会第一时间更新。
暂无评论内容