0%

Python面向对象参考手册

有关Python面向对象的属性,实例,方法,特殊方法合集。

主页

1 类属性、实例属性与类方法、静态方法

1.1 什么是类对象,实例对象

类对象:类名
实例对象:类创建的对象

1.2 类属性

类属性就是类对象所拥有的属性,它被所有类对象的实例对象所共有,在内存中只存在一个副本,这个和C++、Java中类的静态成员变量有点类似。对于公有的类属性,在类外可以通过类对象和实例对象访问

1
2
3
4
5
6
7
8
9
10
class people:
name="Tom" #公有的类属性
__age=18 #私有的类属性

p=people()
print(p.name) #实例对象
print(people.name) #类对象

print(p.__age) #错误 不能在类外通过实例对象访问私有的类属性
print(people.__age) #错误 不能在类外同过类对象访问私有的类属性

1.3 实例属性

1
2
3
4
5
6
7
8
9
10
11
class people:
name="tom"

p=people()
p.age=18

print(p.name)
print(p.age) #实例属性是实例对象特有的,类对象不能拥有

print(people.name)
print(people.age) #错误:实例属性,不能通过类对象调用

也可以将实例属性放在构造方法中

1
2
3
4
5
6
7
8
9
10
11
12
class people:
name="tom"
def __init__(self,age):
self.age=age

p=people(18)

print(p.name)
print(p.age) #实例属性是实例对象特有的,类对象不能拥有

print(people.name)
print(people.age) #错误:实例属性,不能通过类对象调用

类属性和实例属性混合

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
class people:
name="tom" #类属性:实例对象和类对象可以同时调用
def __init__(self,age): #实例属性
self.age=age

p=people(18) #实例对象
p.sex="男" #实例属性

print(p.name)
print(p.age) #实例属性是实例对象特有的,类对象不能拥有
print(p.sex)

print(people.name) #类对象
print(people.age) #错误:实例属性,不能通过类对象调用
print(people.sex) #错误:实例属性,不能通过类对象调用

如果在类外修改类属性,必须通过类对象去引用然后进行修改。如果通过实例对象去引用,会产生一个同名的实例属性,这种方式修改的是实例属性,不会影响到类属性,并且如果通过实例对象引用该名称的属性,实例属性会强制屏蔽掉类属性,即引用的是实例属性,除非删除了该实例属性

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Animal:
name="Panda"

print(Animal.name) #类对象引用类属性
p=Animal()
print(p.name) #实例对象引用类属性时,会产生一个同名的实例属性
p.name="dog" #修改的只是实例属性的,不会影响到类属性
print(p.name) #dog
print(Animal.name) #panda

删除实例属性

del p.name
print(p.name)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
class Test:
num=100 #类属性
def __init__(self):
self.age=18 #实例属性

test1=Test()
test2=Test()

test1.age=19
test2.age=20

print(test1.num) #100
test1.num=200 #如果通过对象去修改类属性,那么Python会自动给这个对象和这个类属性相同名字的实例属性
print(test1.num) #200,只是修改了副本
print(Test.num) #100

del test1.num #删除之后,仍能打印
print(test1.num)

1.4 类方法

即为类对象所拥有的方法,需要用修饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数(当然可以用其他名称的变量作为其第一个参数,但是大部分人都习惯以’cls’作为第一个参数的名字,就最好用’cls’了),能够通过实例对象和类对象去访问。

1
2
3
4
5
6
7
8
9
10
class people:
country="china"

@classmethod
def getCountry(cls):
return cls.country

p=people()
print(p.getCountry()) #实例对象调用类方法
print(people.getCountry()) #类对象调用类方法

类方法还有一个用途就是可以对类属性进行修改:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class people:
country="china"

@classmethod
def getCountry(cls):
return cls.country

@classmethod
def setCountry(cls,country):
cls.country=country

p=people()
print(p.getCountry()) #实例对象调用类方法
print(people.getCountry()) #类对象调用类方法

p.setCountry("Japan")

print(p.getCountry())
print(people.getCountry())

4、静态方法
需要通过修饰器@staticmethod来进行修饰,静态方法不需要多定义参数

1
2
3
4
5
6
7
8
9
10
class people3:
country="china"

@staticmethod
def getCountry():
return people3.country

p=people3()
print(p.getCountry()) #实例对象调用类方法
print(people3.getCountry()) #类对象调用类方法

从类方法和实例方法以及静态方法的定义形式就可以看出来,类方法的第一个参数是类对象cls,那么通过cls引用的必定是类对象的属性和方法;而实例方法的第一个参数是实例对象self,那么通过self引用的可能是类属性、也有可能是实例属性(这个需要具体分析),不过在存在相同名称的类属性和实例属性的情况下,实例属性优先级更高。
静态方法中不需要额外定义参数,因此在静态方法中引用类属性的话,必须通过类对象来引用

2. Python类中的属性和方法大全

2.1特殊属性:

属性 含义
__name__ 类,函数,方法等效的名字。即名称
__module__ 类定义所在的模块名称
__class__ 对象或类所属的类
__bases__ 类的基类(父类)的元组,顺序为他们在基类列表中出现的顺序
__doc__ 类、函数的文档字符串,如果没有定义则为None
__mro__ 类的mro,class.mro()返回的结果都保存在mro中。C3算法帮忙保证类的mro唯一性
__dict__ 类或实例的属性,可写的字典
__qualname__ 类的限定名

2.2 方法

2.2.1 特殊内建函数与查看属性

方法 等效的内建函数 意义
查看属性
__dir__ dir() 返回类或者对象的所有成员名称列表dir()函数操作实例就是调用__dir()__如果没有参数,返回当前局部作用域中的名称列表。使用参数时,尝试返回该对象的有效属性列表
特殊内建函数
locals() 返回当前作用域中的变量字典
globals() 当前模块全局变量的字典

2.2.2 实例化

方法 意义
__new__(self,*args,**kwargs) 示例化一个对象该方法需要返回一个值,如果该值不少cls的实例,则会调用__init__该方法永远都是静态方法调用new方法前还没有实例对象,正常调用完成后会生成实例对象。
__init__(self) 对实例进行初始化,通常用来设置实例属性,基本配置信息等。调用init方法前已经存在实例对象
__del__(self) 实例的引用次数为0时调用。即删除实例时调用。当系统自动调用del方法后实例已经没有对象记录,等着垃圾回收gc来清理。

2.2.3 可视化

方法 等效的内建函数 含义
__str__(self) str() str()函数、format()函数、print()函数调用,需要返回对象的字符串表达式。如果没有定义,就去调用__repr__方法返回字符串的表达。如果__repr__没有定义,就直接返回对象的内存地址信息
__repr__(self) repr() 内建函数repr()对一个对象获取字符串表达。调用__repr__方法返回字符串表达,如果__repr__也没有定义,就直接返回object的定义,显示内存地址信息。
__bytes__(self) bytes() bytes()函数调用,返回一个对象的bytes表达,即返回bytes对象

2.2.4 可哈希(hash)与等等运算符(==)

方法 等效的内建函数 意义
__hash__(self) hash() 内建函数hash()调用的返回值,返回一个整数。如果定义这个方法该类的实例就可hash
__eq__(self) == 对等等操作符,判断2个对象是否相等,返回值bool值定义了这个方法,如果不提供__hash__方法,那么实例对象将不可hash了

2.2.5 bool

方法 对应的内建函数 意义
__bool__(self) bool() 内建函数bool(),或者对象放在逻辑表达式的位置,调整这个函数返回布尔值。
如果对象没有定义__bool__(),就找__len__()返回长度,非0为真
如果__len__()也没有定义,那么所有实例都返回真

2.3 运算符重载

2.3.1 比较运算符重载

特殊方法 运算符 含义
__lt__(self,other) < 小于运算符等效符调用的对应方法 在obj1 < obj2时调用obj1.__lt__(obj2)
__le__(self,other) <= 小于等于运算符等效符调用的对应方法 在obj1 <= obj2时调用obj1.__le__(obj2)
__eq__(self,other) == 等等运算符等效调用的对应方法 在obj1 == obj2时调用obj1.__eq__(obj2)
__gt__(self,other) > 大于运算符等效调用的对应方法 在obj1 > obj2时调用obj1.__gt__(obj2)
__ge__(self,other) >= 大于等于运算符等效调用的对应方法 在obj1 >= obj2时调用obj1.__ge__(obj2)
__ne__(self,other) != 不等运算符等效调用的对应方法 在obj1 != obj2时调用obj1.__ne__(obj2)

2.3.2 算术运算符重载

特殊方法 运算符 含义
__add__(self,other) + 加法运算等效调用的对应方法 在obj1 + obj2时调用obj1.__add__(obj2)
__sub__(self,other) - 减法运算等效调用的对应方法 在obj1 - obj2时调用obj1.__sub__(obj2)
__mul__(self,other) * 乘法运算等效调用的对应方法 在obj1 * obj2时调用obj1.__mul__(obj2)
__truediv__(self,other) / 除法运算等效调用的对应方法 在obj1 / obj2时调用obj1.__truediv__(obj2)
__mod__(self,other) % 取摸运算(取余数)等效调用的对应方法 在obj1 % obj2时调用obj1.__mod__(obj2)
__floordiv__(self,other) // 整除运算(向下取整)等效调用的对应方法 在obj1 // obj2时调用obj1.__floordiv__(obj2)
__pow__(self,other) ** pow(x,n) 次幂运算等效调用的对应方法。也等价于pow(x,n)方法 在obj1 ** obj2时调用obj1.__pow__(obj2)
__divmod__(self,other) divmod(obj1,obj2) 获取数的商和余数组成的元组等效的对应方法 在divmod(obj1,obj2)时调用obj1.__divmod__(obj2)
__matmul__(self,other) @ 矩阵运算符等效调用的对应方法 在obj1 @ obj2时调用obj1.__matmul__(obj2)
__and__(self,other) & 与运算符等效的对应方法
__or__(self,other) 竖线 或运算符等效的对应方法 在obj1 竖线 obj2时调用obj1.__or__(obj2)
__xor__(self,other) ^ 异或运算符等效的对应方法 在obj1 ^ obj2时调用obj1.__xor__(obj2)
__lshift__(self,other) << 左移运算符等效的对应方法 在obj1 << obj2时调用obj1.__lshift__(obj2)
__rshift__(self,other) >> 右移运算符等效的对应方法。 在obj1 >> obj2时调用obj1.__rshift__(obj2)
__invert__(self,other) ~ 按位取反运算符等效的对应方法 在~obj时调用obj.__invert__()

2.3.3 反向运算符重载

特殊方法 运算符 含义
以下示例中。按照__iadd__方法来举例: obj1中必须没有定义对应的方法__add__。或者返回值为NotImplemented。才会调用obj2.__radd__(obj1)来完成运算
__radd__(self,other) + 加法运算等效调用的对应方法 在obj1 + obj2时调用obj2.__radd__(obj1)
__rsub__(self,other) - 减法运算等效调用的对应方法 在obj1 - obj2时调用obj2.__rsub__(obj1)
__rmul__(self,other) * 乘法运算等效调用的对应方法 在obj1 * obj2时调用obj2.__rmul__(obj1)
__rtruediv__(self,other) / 除法运算等效调用的对应方法 在obj1 / obj2时调用obj2.__rtruediv__(obj1)
__rmod__(self,other) % 取摸运算(取余数)等效调用的对应方法 在obj1 % obj2时调用obj2.__rmod__(obj1)
__rfloordiv__(self,other) // 整除运算(向下取整)等效调用的对应方法 在obj1 // obj2时调用obj2.__rfloordiv__(obj1)
__rpow__(self,other) ** pow(x,n) 次幂运算等效调用的对应方法。也等价于pow(x,n)方法 在obj1 ** obj2时调用obj2.__rpow__(obj1)
__rdivmod__(self,other) divmod(obj1,obj2) 获取数的商和余数组成的元组等效的对应方法 如果obj1没有__divmod__方法,或者返回NotImplemented,则会调用obj2.__rdivmod__(obj1)
__rmatmul__(self,other) @ 矩阵运算符等效调用的对应方法 在obj1 @ obj2时调用obj2.__rmatmul__(obj1)
__rand__(self,other) & 与运算符等效的对应方法 在obj1 & obj2时调用obj2.__rand__(obj1)
__ror__(self,other) 竖线 或运算符等效的对应方法 在obj1 竖线 obj2时调用obj2.__ror__(obj1)
__rxor__(self,other) ^ 异或运算符等效的对应方法 在obj1 ^ obj2时调用obj2.__rxor__(obj1)
__rlshift__(self,other) << 左移运算符等效的对应方法 在obj1 << obj2时调用obj2.__rlshift__(obj1)
__rrshift__(self,other) >> 右移运算符等效的对应方法。 在obj1 >> obj2时调用obj2.__rrshift__(obj1)

2.3.4 赋值运算符的重载

特殊方法 运算符 含义
__iadd__(self,other) += 加等赋值运算等效调用的对应方法 在obj1 += obj2时调用obj1 = obj1.__iadd__(obj2)
__isub__(self,other) -= 减等赋值运算等效调用的对应方法 在obj1 -= obj2时调用obj1 = obj1.__isub__(obj2)
__imul__(self,other) *= 乘等赋值运算等效调用的对应方法 在obj1 *= obj2时调用obj1 = obj1.__imul__(obj2)
__itruediv__(self,other) /= 除等赋值运算等效调用的对应方法 在obj1 /= obj2时调用obj1 = obj1.__itruediv__(obj2)
__imod__(self,other) %= 取模等赋值运算等效调用的对应方法 在obj1 %= obj2时调用obj1 = obj1.__imod__(obj2)
__ifloordiv__(self,other) //= 整除等赋值运算符等效调用的对应方法 在obj1 //= obj2时调用obj1 = obj1.__ifloordiv__(obj2)
__ipow__(self,other) **= 次幂等运算符等效调用的对应方法 在obj1 **= obj2时调用obj1 = obj1.__ipow__(obj2)
__imatmul__(self,other) @= 矩阵等赋值运算等效调用的对应方法 在obj1 @= obj2时调用obj1 = obj1.__imatmul__(obj2)
__iand__(self,other) &= 与等赋值运算等效的对应方法 在obj1 &= obj2时调用obj1 = obj1.__iand__(obj2)
__ior__(self,other) 竖线= 或等赋值运算等效的对应方法 在obj1 竖线= obj2时调用obj1 = obj1.__ior__(obj2)
__ixor__(self,other) ^= 异或等赋值运算等效的对应方法 在obj1 ^= obj2时调用obj1 = obj1.__ixor__(obj2)
__ilshift__(self,other) <<= 左移等赋值运算等效的对应方法 在obj1 <<= obj2时调用obj1 = obj1.__ilshift__(obj2)
__irshift__(self,other) >>= 右移等赋值运算等效的对应方法 在obj1 >>= obj2时调用obj1 = obj1.__irshift__(obj2)

3.4 容器相关方法

方法 对应的操作 意义
__len__(self) len(obj) 内建函数len(),返回对象的长度(>=0的整数),如果把对象当做容器类型看,就如同list或者dict。
bool()函数调用的时候,如果没有__bool__()方法,则会看__len__()方法是否存在,存在返回非0为真
__iter__(self) for i in obj 迭代容器时,调用,返回一个新的可迭代对象
__contains__(self,item) x in obj in 成员运算符,没有实现,就默认调用__iter__方法遍历
__getitem__(self,key) obj[key] 实现self[key]访问。序列对象,key接受整数为索引,或者切片。对于set和dict,key为可以hashable(即可哈希)。key不存在引发KeyError异常
__setitem__(self,key) obj[key] = value __getitem__的访问类似,是设置值的方法
__missing__(self,key) 字典或其子类使用__getitem__()调用时,key不存在执行该方法

3.5 可调用对象

方法 等效 意义
__call__(self) obj() 类中定义一个该方法,类的实例就可以像函数一样调用

3.6 上下文管理

方法 等价语法 意义
__enter__(self) with obj() as c:pass进入语句块之前执行 进入与此对象相关的上下文,如果存在该方法,with语法会把该方法的返回值绑定到as子句中指定的变量上
__exit__(self, exc_type, exc_value, traceback) with obj() as c:pass退出时执行 退出与此对象相关的上下文。时执行

3.7 反射

内建函数 意义
getattr(object,name[,default]) 通过name返回object的属性值。当属性不存在,将使用default返回,如果没有default,则会抛出AttributeError异常。name必须为字符串
setattr(object,name,value) object的属性存在,则覆盖,不存在,新增
hasattr(object,name) 判断对象是否有这个名字的属性,name必须为字符串
方法 对应的内建函数 意义
__getattr__(self,item) 当通过搜索实例、实例的类及祖先类查不到属性,就会调用此方法
__setattr_(slef,key,values) setattr(object,name,value) 通过,访问实例属性,进行增加、修改都要调用它
__delattr__(self,item) del obj.k 当通过实例来删除属性时调用此方法
__getattribute__() getattr(object,name[,default]) 实例所有的属性调用都从这个方法开始

3.8.描述器

魔术方法 说明
__get__(self,instance,owner) 获取所有者类的属性,定义了该函数,那么该类就是一个”非数据描述器”
__set__(self,instance,value) 设置所有者类的属性,如果一个”非数据描述器”定义了该函数,那么就是”数据描述器”
__delete__(self,instance) 删除所有者类的属性
如果您觉得还不错,可以请我喝杯咖啡。