根类object
在 Python 中,所有类的根类都是object
,即object
是所有类的父类,因此所有类都具有object
类的属性和方法,实例代码如下:
# 创建根类的对象
obj = object()
# dir 函数,返回根类 object 的所有属性和方法
print(dir(obj))
示例输出:
['__class__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__']
object 类中常用的属性和方法:
1. __slots__
属性
该属性用于限制类中的实例属性。
当定义一个类,并创建该类的对象后,如果需要给该对象添加属性和方法,则可以通过在类外动态地给该对象添加任何属性和方法,只不过动态的添加方法需要使用types
模块中的MethodType
类,
进而将普通的函数转变为类中的实例方法,实例代码如下:
from types import MethodType
class Car(object):
pass
car = Car()
car.name = '小毛驴'
print(car.name)
def carInfo(self):
print(f"车辆名称: {self.name}")
car.carInfo = MethodType(carInfo, car)
car.carInfo()
示例输出:
小毛驴
车辆名称: 小毛驴
但是,如果想限制类中的实例属性,例如,只想在类中添加实例属性name
和price
,这时候就需要定义一个特殊的属性__slots__
,来限制类中的实例属性,实例代码如下:
class Car(object):
# 可以将允许添加的实例属性放在元组之中
__slots__ = ('name', 'price')
car = Car()
car.name = '小毛驴'
print(car.name)
car.engine = '四条腿'
# 报错,因为Car类只允许添加实例属性name和price
# AttributeError: 'Car' object has no attribute 'engine' and no __dict__ for setting new attributes
print(car.engine)
需要注意的是,__slots__
属性限制的实例属性仅对当前类的对象起作用,对继承的子类是不起作用的,如果也想限制子类中的实例属性,则需要在子类中也定义__slots__
变量,实例代码如下:
class Car(object):
__slots__ = ('name', 'price')
# CarSon1类的实例属性不受限制
class CarSon1(Car):
pass
car1 = CarSon1()
car1.engine = '四条腿'
print(car1.engine)
# CarSon2类的实例属性受限制
class CarSon2(Car):
__slots__ = ('name', 'price')
car2 = CarSon2()
car2.engine = '八条腿'
# 报错,因为Benz类只允许添加实例属性name和price
print(car2.engine)
2.__dict__
属性
在 Python 中,无论是实例属性还是类属性,都是以字典的形式进行存储的,其中属性名作为字典的键,而属性值作为该键对应的值。通过 Python 提供的__dict__
属性,可以查看该类中的属性。
该属性可以用类或者类的对象来调用(两者输出结果不一样,不要混为一谈),如果使用类.__dict__
的形式,则输出由该类中所有类属性组成的字典;如果使用类的对象.__dict__
的形式,则输出由该对象所有实例属性组成的字典,示例代码如下:
class Car(object):
oil = [92, 95, 98]
def __init__(self):
self.name = "这是汽车的名字"
self.price = "这是汽车的价格"
# 通过类名调用__dict__属性
print(f'类属性:{Car.__dict__}')
# 通过类的对象调用__dict__属性
car = Car()
print(f'实例属性:{car.__dict__}')
示例输出:
类属性:{'__module__': '__main__', '__firstlineno__': 1, 'oil': [92, 95, 98], '__init__': <function Car.__init__ at 0x00000256863A3240>, '__static_attributes__': ('name', 'price'), '__dict__': <attribute '__dict__' of 'Car' objects>, '__weakref__': <attribute '__weakref__' of 'Car' objects>, '__doc__': None}
实例属性:{'name': '这是汽车的名字', 'price': '这是汽车的价格'}
两种调用的主要区别:
1.类.__dict__
包含类的属性、方法、类方法、静态方法;
包含特殊属性(如
__module__
、__doc__
等);通常不包含实例属性。
2.类的对象.__dict__
只包含该实例特有的属性;
不包含类的方法和类的属性;
每个实例都有独立的
__dict__
。
除了可以使用__dict__
属性查看类中的属性之外,还可以通过类的对象.__dict__[实例属性]
的形式对类中的实例属性值进行修改,但需要注意的是,不可以通过该方法修改类的属性,示例代码如下:
class Car(object):
oil = [92, 95, 98]
def __init__(self):
self.name = "这是汽车的名字"
self.price = "这是汽车的价格"
# 使用类的对象调用__dict__属性修改实例属性的值
car = Car()
print(car.name)
car.__dict__['name'] = '汽车类'
print(car.name)
# 不可以使用类名调用__dict__属性修改类属性的值
print(Car.__dict__)
# 报错
Car.__dict__['oil'] = [95, 98]
print(Car.oil)
另外,对于具有继承关系的父类和子类来讲,子类不会包含父类的__dict__
属性,即父类和子类拥有各自的__dict__
属性,示例代码如下:
class Car(object):
oil = [92, 95, 98]
def __init__(self):
self.name = "这是汽车的名字"
self.price = "这是汽车的价格"
class Audi(Car):
oil = [95, 98]
def __init__(self):
super().__init__()
self.car_name = "奥迪"
self.car_price = [15, 20, 30, 40, 50, 60, 70, 80, 90, 100]
# 通过父类名调用__dict__属性
print(f'父类的类属性:{Car.__dict__}')
car = Car()
# 通过父类的对象调用__dict__属性
print(f'父类的实例属性:{car.__dict__}')
# 通过子类名调用__dict__属性
print(f'子类的属性:{Audi.__dict__}')
audi = Audi()
# 通过子类的对象调用__dict__属性
print(f'子类的实例属性:{audi.__dict__}')
示例输出:
父类的类属性:{'__module__': '__main__', '__firstlineno__': 1, 'oil': [92, 95, 98], '__init__': <function Car.__init__ at 0x00000298372160C0>, '__static_attributes__': ('name', 'price'), '__dict__': <attribute '__dict__' of 'Car' objects>, '__weakref__': <attribute '__weakref__' of 'Car' objects>, '__doc__': None}
父类的实例属性:{'name': '这是汽车的名字', 'price': '这是汽车的价格'}
子类的属性:{'__module__': '__main__', '__firstlineno__': 9, 'oil': [95, 98], '__init__': <function Audi.__init__ at 0x00000298351AFA60>, '__static_attributes__': ('car_name', 'car_price'), '__doc__': None}
子类的实例属性:{'name': '这是汽车的名字', 'price': '这是汽车的价格', 'car_name': '奥迪', 'car_price': [15, 20, 30, 40, 50, 60, 70, 80, 90, 100]}
3.__bases__
属性
该属性用于查看类的所有直接父类,返回所有直接父类组成的元组,示例代码如下:
class Car(object):
pass
class DasAuto(object):
pass
class Audi(Car, DasAuto):
pass
print('Car的所有父类:', Car.__bases__)
print('DasAuto的所有父类:', DasAuto.__bases__)
print('Audi的所有父类:', Audi.__bases__)
示例输出:
Car的所有父类: (<class 'object'>,)
DasAuto的所有父类: (<class 'object'>,)
Audi的所有父类: (<class '__main__.Car'>, <class '__main__.DasAuto'>)
注意,如果要查看的类没有直接父类,则返回默认的直接父类——根类object
4.__subclasses__()
方法
该方法用于查看类的所有直接子类,返回所有直接子类所组成的列表,示例代码如下:
class Car(object):
pass
class Audi(Car):
pass
class BMW(Car):
pass
print('Car的所有子类:', Car.__subclasses__())
示例输出:
Car的所有子类: [<class '__main__.Audi'>, <class '__main__.BMW'>]
5.__str__()
方法
该方法用于描述类的对象,当使用print()
函数时触发。
在 Python 中,使用print()
函数输出类的对象的名称时,默认情况下,会输出类的对象所引用的内存地址,示例代码如下:
class Car(object):
def __init__(self):
pass
car = Car()
print(car)
示例输出:
<__main__.Car object at 0x000002AF8B4D8EC0>
如果希望输出类的对象的相关描述,则可以使用__str__()
方法,示例代码如下:
class Car(object):
def __init__(self):
pass
def __str__(self):
return ('这是汽车类')
car = Car()
print(car)
示例输出:
这是汽车类
6.__repr__()
方法
该方法的用法与__str__()
方法一致,唯一的区别是__repr__()
方法既可以在使用print()
函数时触发,又可以在命令行中直接输出类的对象时触发,而__str__()
方法在命令行中直接输出类的对象时只能输出类的对象所引用的内存地址。
在 Python IDLE 中运行,示例代码如下:__str__()
>>> class Car(object):
··· def __init__(self):
··· pass
··· def __str__(self):
··· return('这是汽车类')
>>> car = Car()
>>> car
<<< <__main__.Car object at 0x00000218D66BA510>
__repr__()
>>> class Car(object):
··· def __init__(self):
··· pass
··· def __repr__(self):
··· return('这是汽车类')
>>> car = Car()
>>> car
<<< 这是汽车类
__repr__()
方法在 IDE 中使用 print()
函数触发与__str__()
方法相同。
7.__call__()
方法
该方法可以让类的对象具有类似函数的使用方法,当以类的对象()
的形式使用时触发。
如果类的对象中只有一种方法,并且该类的对象存在频繁使用的情况,则可以通过__call__()
方法来简化调用,示例代码如下:
class Car(object):
def __init__(self):
pass
def __call__(self):
print('这是一个汽车类')
car = Car()
car()
示例输出:
这是一个汽车类
8.__eq__()
方法
该方法用于设置两个类的对象相等的条件,当两个类的对象使用比较运算符==
时触发。__eq__()
方法默认有两个参数,一个是参数self
,另一个参数是other
,表示自身 的属性和其他对象的属性分别进行比较,如果相等,则返回值为True
,否则返回值为False
,示例代码如下:
class Car(object):
def __init__(self, name, price):
self.name = name
self.price = price
def __eq__(self, other):
if self.name == other.name and self.price == other.price:
return True
else:
return False
car1 = Car('car', '100000')
car2 = Car('car', '100000')
car3 = Car('car', '200000')
print(car1 == car2)
print(car1 == car3)
示例输出:
True
False