classClassname:@staticmethoddef fun():print('静态方法')@classmethoddef a(cls):print('类方法')# 普通方法def b(self):print('普通方法')Classname.fun()Classname.a()
C =Classname()
C.fun()
C.a()
C.b()
反向运算符重载:
__radd__: 加运算
__rsub__: 减运算
__rmul__: 乘运算
__rdiv__: 除运算
__rmod__: 求余运算
__rpow__: 乘方
复合重载运算符:
__iadd__: 加运算
__isub__: 减运算
__imul__: 乘运算
__idiv__: 除运算
__imod__: 求余运算
__ipow__: 乘方
Python3 类方法总结
普通方法:对象访问
私有方法:两个下划线开头,只能在类内部访问
静态方法:类和对象访问,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
类方法:类和对象访问,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的
多继承情况下:从左到右查找方法,找到为止,不然就抛出异常
classPeople:# 定义基本属性
name=''
age=0# 定义私有属性外部无法直接访问
__weight=0def __init__(self,n,a,w):self.name = n
self.age = a
self.__weight = w
def speak(self):print("%s say : i am %d."%(self.name,self.age))
p =People('Python',10,20)
p.speak()# __weight无法直接访问print(p.name,'--',p.age)#,'--',p.__weight)
针对 __str__ 方法给出一个比较直观的例子:
class people: def __init__(self,name,age): self.name=name self.age=age def __str__(self): return '这个人的名字是%s,已经有%d岁了!'%(self.name,self.age) a=people('孙悟空',999) print(a)
输出:
这个人的名字是孙悟空,已经有999岁了! 如果没有重载函数的话输出的就是一串看不懂的字符串: <__main__.people object at 0x00000272A730D278>
Python3 中类的静态方法、普通方法、类方法
静态方法: 用 @staticmethod 装饰的不带 self 参数的方法叫做静态方法,类的静态方法可以没有参数,可以直接使用类名调用。
普通方法: 默认有个self参数,且只能被对象调用。
类方法: 默认有个 cls 参数,可以被类和对象调用,需要加上 @classmethod 装饰器。
class Classname: @staticmethod def fun(): print('静态方法') @classmethod def a(cls): print('类方法') # 普通方法 def b(self): print('普通方法') Classname.fun() Classname.a() C = Classname() C.fun() C.a() C.b()
反向运算符重载:
复合重载运算符:
Python3 类方法总结
class People: # 定义基本属性 name='' age=0 # 定义私有属性外部无法直接访问 __weight=0 def __init__(self,n,a,w): self.name = n self.age = a self.__weight = w def speak(self): print("%s say : i am %d."%(self.name,self.age)) p = People('Python',10,20) p.speak() # __weight无法直接访问 print(p.name,'--',p.age)#,'--',p.__weight)
继承
单继承:
class Student(People): grade='' def __init__(self,n,a,w,g): People.__init__(self,n,a,w) self.grade = g # 覆写父类方法 def speak(): print("%s 说: 我 %d 岁了,我在读 %d 年级"%(self.name,self.age,self.grade)) class Speak(): topic='' name='' def __init__(self,n,t): self.name = n self.topic = t # 普通方法,对象调用 def speak(self): print("我叫 %s,我是一个演说家,我演讲的主题是 %s"%(self.name,self.topic)) # 私有方法,self调用 def __song(self): print('唱一首歌自己听',self); # 静态方法,对象和类调用,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的 @staticmethod def song(): print('唱一首歌给类听:静态方法'); # 普通方法,对象调用 def song(self): print('唱一首歌给你们听',self); # 类方法,对象和类调用,不能和其他方法重名,不然会相互覆盖,后面定义的会覆盖前面的 @classmethod def song(self): print('唱一首歌给类听:类方法',self)
多继承:
class Sample(Speak,Student): a = '' def __init__(self,n,a,w,g,t): Student.__init__(self,n,a,w,g) Speak.__init__(self,n,t) test = Sample('Song',24,56,7,'Python') test.speak() test.song() Sample.song() Sample.song() test.song() # test.__song() 无法访问私有方法
所有专有方法中,__init__()要求无返回值,或者返回 None。而其他方法,如__str__()、__add__()等,一般都是要返回值的,如下所示:
>>> class Complex: ... def __init__(self, realpart, imagpart): ... self.r = realpart ... self.i = imagpart ... return 'hello' ... >>> x = Complex(3.0, -4.5) Traceback (most recent call last): File "<stdin>", line 1, in <module> TypeError: __init__() should return None, not 'str'
而对于 __str__()、__add__() 等。
def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __repr__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): if other.__class__ is Vector: return Vector(self.a + other.a, self.b + other.b) elif other.__class__ is int: return Vector(self.a+other,self.b)
类的专有方法中,也是存在默认优先级的,多个方法都有返回值,但一般优先取 __str__() 的返回值,如下面例子:
class Vector: def __init__(self, a, b): self.a = a self.b = b def __repr__(self): return 'Vector (%d, %d)' % (self.b, self.a) def __str__(self): return 'Vector (%d, %d)' % (self.a, self.b) def __add__(self,other): return Vector(self.a + other.a, self.b + other.b) v1 = Vector(2,10) print (v1)
结果是 Vector(2,10),而不是 Vector(10,2)。这里优先使用 __str__() 的返回值。
v1.__repr__()
结果是:Vector(10,2)
__str__函数
__str__ 是一个类的方法,在打印类对象,获取其属性信息时调用。打印一个实例化对象时,默认打印的其实时一个对象的地址,但是我们可以对其进行重载,打印我们想要的信息。例如上面的例子中进行的重载。
在类的方法中直接修改 self 是无效操作,即使 self 变量的地址与实例地址相同:
class C: def __init__(self, a): self.a = a def construct(self, a): c = C(a) self = c def getid(self): return id(self) if __name__ == '__main__': c1 = C(2) c1.construct(3) # c1.a == 2 print(id(c1) == c1.getid()) # True
事实上 class 的私有属性在外部也是可以访问的我们可以看下文中的例子。
#!/usr/bin/python3 class People: def __init__(self, name, age, ): self.name = name self.age = age self.__privater_var = 10 def intro(self): print(f'My name is {self.name},I\'m {self.age}') def get_var(self): print(self.__privater_var) def set_var(self, var): self.__privater_var = var someone = People(name='jack', age=20) someone.intro() print(someone.age) someone.get_var() # 通过get_var方法访问私有属性__privater_var,值为10 someone.set_var(30) # 通过set_var方法修改私有属性__privater_var,值为30 someone.get_var() # 再次通过get_var方法访问私有属性__privater_var,值为30
结果:
My name is jack,I'm 20 20 10 30
接下下来看看为什么我们使用someone.__privater_var会报错呢?
AttributeError: 'People' object has no attribute '__privater_var'
这里我们先使用 dir() 函数:
print(dir(someone)) # 获得当前someone的属性列表
结果:
['_People__privater_var', '__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__', 'age', 'get_var', 'intro', 'name', 'set_var']
从打印出的结果中,我们并没有找到'_peivater_var'但是我们看到一个'_People__privater_var'.有没有想到什么?原来是被重命名了。好,我们来试试:
print(someone._People__privater_var) someone._People__privater_var = 40 print(someone._People__privater_var)
结果:
30 40
所以说,私有变量的属性是可以修改的。既然Python阻止访问,一般情况下就不要访问。