python3  面向对象编程2

类方法:

@classmethod

作用:1,类方法是只能访问类变量的方法;

2,类方法需要使用@classmethod 装饰器定义;

3,类方法的第一个参数是类的实例, 约定写成cls

说明:1, 类实例和对象实例都可以调用类方法;

2, 类方法不能方法实例变量

类方法和实例方法对比:

1,类方法能够访问类变量,不能访问实例变量;

实例方法能够访问类变量,也能访问实例变量

2,类方法可以用实例来调用,也可以用类来调用;

实例方法在调用时必须传入实例;

 class Bank:
moneys = 10000000 #一千万
@classmethod
def total_money(cls):
print("某银行总行资金数:", cls.moneys) def __init__(self, b):
self.branch = b
self.moneys = 5000000
self.__class__.moneys -= 5000000 Bank.total_money() #某银行总行资金数: 10000000
b1 = Bank("xxx地址支行")
b1.total_money() #某银行总行资金数: 5000000

静态方法

@staticmethod

作用:1, 静态方法是普通的函数;

2,静态方法定义在类的内部,只能凭借该类和实例调用

3,静态方法需要使用@staticmethod 装饰器定义

4,静态方法与普通函数定义相同,不需要传入self实例参数和cls类参数;

说明:1, 类实例和对象实例都可以调用静态方法;

2, 静态方法不能访问类变量和实例变量;

 class A:
@staticmethod
def myadd(a, b):
return a + b print(A.myadd(100, 200)) #
a = A()
print(a.myadd(200, 300)) #

实例方法,类方法,静态方法总结:

不想访问类变量的实例变量(属性),用静态方法;

只想访问类内变量,不想访问实例属性用类方法;

既想访问类内变量,也想访问实例变量用实例方法;

特性属性

@property         用来模拟一个属性;

通过@property 装饰器可以对模拟属性赋值和取值加以控制失效其他语言所拥有的getter 和 setter 功能;

 import math

 class Circle:

     def __init__(self,r):  #圆类
self.radius = r #半径 @property
def area(self): #面积
print("area函数被调用。。。")
return math.pi * self.radius ** 2 def area(self, a): #a代表面积
self.radius = math.sqrt(a/math.pi) c1 = Circle(10)
print(c1.area)
#area函数被调用。。。
#314.1592653589793
c1.area = 31415.926
print(c1.radius)
print(c1.area)
#<bound method Circle.area of <__main__.Circle object at 0x00000000021ABB00>>
#
#31415.926

函数  id

id(obj)  返回对象的标识(identity);

例: id(a) == id(a1)  #F

 >>> class A:
pass >>> a = A()
>>> a1 = A()
>>> a is a1
False
>>> id(a)
54961992
>>> id(a1)
54905488
>>> a
<__main__.A object at 0x000000000346A748>
>>> 0x000000000346A748
54961992
>>>

运算符重载

什么是运算符重载?

用自定义的规则实现实例之间的运算符操作或函数操作;

作用:

1, 让实例像数学表达式一样的进行运算操作;

2, 让实例像内建对象一样函数操作;

3, 让程序简洁起来;

对象转字符串函数重载方法;

repr()    函数的重载方法:

def  __repr__(self):

.....

str( )    函数的重载方法:

def   __str__(str):

....

注: 如果对象没有__str__方法, 则用repr(obj)函数的结果代替;

 class MyNumber:
"此类用于定义一个整型数字类,用于演示str函数重载"
def __init__(self,v):
self.data = v def __repr__(self):
print("__repr__被调用")
return "MyNumber(" + repr(self.data) + ")" def __str__(self):
print("__str__被调用")
return "整数数值(" + str(self.data) + ")" n1 = MyNumber(100)
n2 = MyNumber(200)
print(repr(n1))
print(str(n2))
#__repr__被调用
#MyNumber(100)
#__str__被调用
#整数数值(200)
print(n2) #等同于print(str(n2))
#__str__被调用
#整数数值(200)
print(n1,(1,2,3),2j)
#__str__被调用
#整数数值(100) (1, 2, 3) 2j

算数运算符的重载:

+              __add__

-               __sub__

*               __mul__

/                __truediv__

//               __floordiv__

%              __mod__

**              __pow__

二元运算符的重载的格式;

def  __xxx__(self,   other):

....

注: 二元运算符的重载方法的参数列表找中只能有两个参数;

重载说明: 运算符重载的方法参数已经有固定的含义,不可改变原有意义,除 __call__方法之外,其他重载方法的参数个数不可改变;

练习1: 自定义两个列表类;

 class MyList:

     def __init__(self, a):
self.data = a.copy() def infos(self):
return "MyList(" + str(self.data) + ")" def __str__(self):
return self.infos() L = [1,2,3]
L1 = MyList(L)
#L[2] = 3.14
print(L1.infos()) #MyList([1, 2, 3])
print(L1) #MyList([1, 2, 3])
L2 = MyList([4,5,6])
print(L2.infos()) #MyList([4, 5, 6])
print(L2) #MyList([4, 5, 6])

练习2: 实现两个类相加;

 #自定义两个列表类,实现两个列表类相加
class MyList: def __init__(self, a):
self.data = a.copy() def infos(self):
return "MyList(" + str(self.data) + ")" def __str__(self):
return self.infos() def myadd(self,other):
r = []
r.extend(self.data)
r.extend(other.data)
#self.data.clear() #L1 = MyList([])
#other.data.clear() #L2 = MyList([])
return MyList(r) L1 = MyList([1,2,3])
L2 = MyList([4,5,6])
L3 = L1.myadd(L2)
print("L1=",L1)
print("L2=",L2)
#L3 = L1 + L2
print(L3) #MyList([1, 2, 3, 4, 5, 6])
 class MyList:

     def __init__(self, a):
self.data = a.copy() def infos(self):
return "MyList(" + str(self.data) + ")" def __str__(self):
return self.infos() def myadd(self,other):
r = []
r.extend(self.data)
r.extend(other.data)
#self.data.clear() #L1 = MyList([])
#other.data.clear() #L2 = MyList([])
return MyList(r) def __add__(self, other):
return self.myadd(other) L1 = MyList([1,2,3])
L2 = MyList([4,5,6])
#L3 = L1.myadd(L2)
L3 = L1 + L2
print("L1=",L1)
print("L2=",L2)
print(L3) #MyList([1, 2, 3, 4, 5, 6])
 class MyList:

     def __init__(self, a):
self.data = a.copy() def infos(self):
return "MyList(" + str(self.data) + ")" def __str__(self):
return self.infos() def myadd(self,other):
r = []
r.extend(self.data)
if type(other) == int:
r.append(other)
elif type(other) == MyList:
r.extend(other.data)
else:
raise ValueError("other 不能出现其他值")
#self.data.clear() #L1 = MyList([])
#other.data.clear() #L2 = MyList([])
return MyList(r) def __add__(self, other):
return self.myadd(other) L1 = MyList([1,2,3])
L2 = MyList([4,5,6])
#L3 = L1.myadd(L2)
L3 = L1 + L2
print("L1=",L1)
print("L2=",L2)
print(L3) #MyList([1, 2, 3, 4, 5, 6])
L3 = L1 + 10 #追加一个值
print(L3) #MyList([1, 2, 3, 10])
 class MyList:

     def __init__(self, a):
self.data = a.copy() def infos(self):
return "MyList(" + str(self.data) + ")" def __str__(self):
return self.infos() #def myadd(self,other):
# r = []
# r.extend(self.data)
# if type(other) == int:
# r.append(other)
# elif type(other) == MyList:
# r.extend(other.data)
# else:
# raise ValueError("other 不能出现其他值")
# #self.data.clear() #L1 = MyList([])
# #other.data.clear() #L2 = MyList([])
# return MyList(r) def __add__(self, other):
return self.myadd(other) def __mul__(self, rhs): #right hand side
return MyList(self.data * rhs)
#以下方法可以实现
#L0 = MyList([])
#for x in range(rhs):
# L0 += MyList(self.data)
#return L0 L1 = MyList([1,2,3])
L2 = MyList([4,5,6])
L3 = L1 * 3
print(L3) #MyList([1, 2, 3, 1, 2, 3, 1, 2, 3])

反向算数运算符重载;

+              __radd__ (self,  lhs)            # 加法    lhs +  self

-               __rsub__(self,  lhs)             # 减法    lhs -  self

*               __rmul__(self,  lhs)             # 乘法    lhs *  self

/                __rtruediv__(self,  lhs)        # 除法    lhs /  self

//               __rfloordiv__(self,  lhs)       #地板除  lhs //  self

%              __rmod__(self,  lhs)           #求余(取模)  lhs %  self

**              __rpow__(self,  lhs)            #幂  lhs **  self

3
 class MyList:

     def __init__(self, a):
self.data = a.copy() def __str__(self):
return "MyList("+ str(self.data) +")" def __mul__(self, rhs): #right hand side
return MyList(self.data * rhs) def __rmul__(self, lhs): #左
#return MyList(self.data * lhs)
#return self * lhs
return self.__mul__(lhs) L1 = MyList([1,2,3])
L2 = MyList([4,5,6])
L3 = 3 * L1
print(L3) #MyList([1, 2, 3, 1, 2, 3, 1, 2, 3])

复合赋值运算符:

__iadd__(self, rhs)            #加法   self  +=  rhs

__isub__(self, rhs)             #减法   self  -=  rhs

__imul__(self, rhs)             #乘法   self  *=  rhs

__itruediv__(self, rhs)        #除法   self  /= rhs

__ifloordiv__(self, rhs)       #地板除   self /= rhs

__imod__(self, rhs)           #取模(求余) self %= rhs

__ipow__(self, rhs)           #幂    self **= rhs

 class MyList:
def __init__(self,a):
self.data = a.copy() def __str__(self):
return "MyList("+ str(self.data) +")" def __mul__(self, rhs): #right hand side
print("__mul__")
return MyList(self.data * rhs) def __imul__(self, rhs):
print("__imul__")
self.data = self.data * rhs
return self L1 = MyList([1,2,3])
L1 *= 2
print(L1)
#__mul__
#MyList([1, 2, 3, 1, 2, 3])

一元运算符的重载:

__neg__      -(负号)

__pos__      +(正号)

__invert__   ~(取反)

重载方法:

def  __xxx__(self):

....

 class MyList:

     def __init__(self, a):
self.data = a.copy() def __str__(self):
return "MyList("+ str(self.data) +")" def __neg__(self):
ml = MyList(self.data)
for i in range(len(ml.data)):
ml.data[i] = -ml.data[i]
return ml L1 = MyList([1,2,3])
L3 = -L1
print(L3) #MyList([-1, -2, -3])
 class MyList:

     def __init__(self, a):
self.data = a.copy() def __str__(self):
return "MyList("+ str(self.data) +")" def __invert__(self):
ml = MyList(self.data)
ml.data.reverse()
return ml L1 = MyList([1,2,3])
L3 = ~L1
print(L3) #MyList([3, 2, 1])

比较运算符的重载:

__lt__      <  小于
__le__    <=

__gt__    >

__ge__   >=

__eq__   ==

__ne__  !=

比较运算的通常用于返回True 和 False;

 class Tree:
def __init__(self, h): #h 树的高度
self.height = h def show(self):
"描述"
print(" * ")
print("***")
print(" * ")
print(" * ") def __lt__(self, rhs):
print("__lt__")
return self.height < rhs.height def __le__(self,rhs):
print("__le__")
return self.height < rhs.height def __gt__(self, rhs):
return not (self <= rhs) t1 = Tree(5)
t2 = Tree(10)
if t1 < t2:
print("t2树高")
else:
print("t1树高")
print(t1 <= t2)
print(t1 > t2)

位运算符重载

__invert__   ~取反

__and__      &位与

__or__         |  位或

__xor__       ^ 位异或

__lshift__     <<   左移

__rshift__     >>    右移

内建函数的重载:

__abs__      abs(obj)         函数调用

__len__       len(obj)

__reversed__     reversed(obj)

__round__         round(obj)

 class MyList:

     def __init__(self, a):
self.data = a.copy() def __str__(self):
return "MyList("+ str(self.data) +")" def __abs__(self):
temp = self.data.copy() #列表
for i in range(len(temp)):
if temp[i] < 0:
temp[i] = -temp[i]
return MyList(temp) L1 = MyList([1,-2,3,-4])
L2 = abs(L1)
print(L2) #MyList([1, 2, 3, 4])

repr()   __repr__

str()   _str__

__add__   self + other

__radd__   other + self

__iadd__   self += other

最新文章

  1. word20161213
  2. requestAnimationFrame制作动画:旋转风车
  3. 【转】iOS10项目打包上传被拒关于隐私权限问题
  4. (二)java特征
  5. jquery hasClass()、is() 多个
  6. Unix C++(boost) 线程同步和线程组
  7. sprintf()详细介绍
  8. .Net 异步方法, await async 使用
  9. 使用C++将OpenCV中Mat的数据写入二进制文件,用Matlab读出
  10. starting Tomcat v8.5 at localhost has encountered a problem
  11. POJ 3264 Balanced Lineup 【线段树】
  12. Java查找出现的单词
  13. html5-textarea元素
  14. supervisord 知识点
  15. Golang Context 详细介绍
  16. 再谈CentOS 7程序自启动
  17. Java设计模式(2)单态模式(Singleton模式)
  18. w10下Oracle 11g完全干净卸载
  19. GCC 提供的原子操作
  20. SQL学习笔记五之MySQL索引原理与慢查询优化

热门文章

  1. oracle 日常设置
  2. Eclipse集成weblogic教程
  3. linux常用文本编缉命令(strings/sed/awk/cut)
  4. 使用MongoDB数据库(1)(三十五)
  5. 转 举例说明使用MATLAB Coder从MATLAB生成C/C++代码步骤
  6. Vue笔记:使用 vuex 管理应用状态
  7. js的event.preventDefault()与event.stopPropagation()
  8. Mysql InnoDB三大特性-- change buffer
  9. OPENWRT安装配置指南之 17.01.4 LEDE
  10. vue-1-模板语法