Python之路,第十八篇:Python入门与基础18

python3  面向对象编程2

 类方法:

         @classmethod

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

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

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

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

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

 

类方法和实例方法对比:

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

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

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

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

 1 class Bank:
 2     moneys = 10000000 #一千万
 3     @classmethod
 4     def total_money(cls):
 5         print("某银行总行资金数:", cls.moneys)
 6 
 7     def __init__(self, b):
 8         self.branch = b
 9         self.moneys = 5000000
10         self.__class__.moneys -= 5000000
11 
12 
13 Bank.total_money() #某银行总行资金数: 10000000
14 b1 = Bank("xxx地址支行")
15 b1.total_money() #某银行总行资金数: 5000000
View Code

 

静态方法

        @staticmethod

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

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

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

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

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

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

1 class A:
2     @staticmethod
3     def myadd(a, b):
4         return a + b
5 
6 
7 print(A.myadd(100, 200))  #300
8 a = A()
9 print(a.myadd(200, 300))  #500
View Code

 

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

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

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

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

 

特性属性 

          @property         用来模拟一个属性;

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

 1 import math
 2 
 3 class Circle:
 4 
 5     def __init__(self,r):  #圆类
 6         self.radius = r #半径
 7 
 8     @property
 9     def area(self):   #面积
10         print("area函数被调用。。。")
11         return math.pi * self.radius ** 2
12 
13     def area(self, a):  #a代表面积
14         self.radius = math.sqrt(a/math.pi)
15 
16 
17 c1 = Circle(10)
18 print(c1.area)
19 #area函数被调用。。。
20 #314.1592653589793
21 c1.area = 31415.926
22 print(c1.radius)
23 print(c1.area)
24 #<bound method Circle.area of <__main__.Circle object at 0x00000000021ABB00>>
25 #10
26 #31415.926
View Code

 

 

函数  id

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

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

 1 >>> class A:
 2     pass
 3 
 4 >>> a = A()
 5 >>> a1 = A()
 6 >>> a is a1
 7 False
 8 >>> id(a)
 9 54961992
10 >>> id(a1)
11 54905488
12 >>> a
13 <__main__.A object at 0x000000000346A748>
14 >>> 0x000000000346A748
15 54961992
16 >>> 
View Code

 

运算符重载

什么是运算符重载?

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

作用:

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

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

       3, 让程序简洁起来;

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

        repr()    函数的重载方法:

         def  __repr__(self):

               .....

        str( )    函数的重载方法:

        def   __str__(str):

              ....

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

 

 1 class MyNumber:
 2     "此类用于定义一个整型数字类,用于演示str函数重载"
 3     def __init__(self,v):
 4         self.data = v
 5 
 6     def __repr__(self):
 7         print("__repr__被调用")
 8         return "MyNumber(" + repr(self.data) + ")"
 9 
10     def __str__(self):
11         print("__str__被调用")
12         return "整数数值(" + str(self.data) + ")"
13 
14 
15 n1 = MyNumber(100)
16 n2 = MyNumber(200)
17 print(repr(n1))
18 print(str(n2))
19 #__repr__被调用
20 #MyNumber(100)
21 #__str__被调用
22 #整数数值(200)
23 print(n2) #等同于print(str(n2))
24 #__str__被调用
25 #整数数值(200)
26 print(n1,(1,2,3),2j) 
27 #__str__被调用
28 #整数数值(100) (1, 2, 3) 2j
View Code

 

 

 算数运算符的重载:

+              __add__

-               __sub__

*               __mul__

/                __truediv__

//               __floordiv__

%              __mod__

**              __pow__

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

       def  __xxx__(self,   other):

                ....

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

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

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

 1 class MyList:
 2 
 3     def __init__(self, a):
 4         self.data = a.copy()
 5 
 6     def infos(self):
 7         return "MyList(" + str(self.data) + ")"
 8 
 9     def __str__(self):
10         return self.infos()
11 
12 
13 L = [1,2,3]
14 L1 = MyList(L)
15 #L[2] = 3.14
16 print(L1.infos()) #MyList([1, 2, 3])
17 print(L1)        #MyList([1, 2, 3])
18 L2 = MyList([4,5,6])
19 print(L2.infos()) #MyList([4, 5, 6])
20 print(L2)         #MyList([4, 5, 6])
View Code

 

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

 1 #自定义两个列表类,实现两个列表类相加
 2 class MyList:
 3 
 4     def __init__(self, a):
 5         self.data = a.copy()
 6 
 7     def infos(self):
 8         return "MyList(" + str(self.data) + ")"
 9 
10     def __str__(self):
11         return self.infos()
12 
13     def myadd(self,other):
14         r = []
15         r.extend(self.data)
16         r.extend(other.data)
17         #self.data.clear()   #L1 = MyList([])
18         #other.data.clear()  #L2 = MyList([])
19         return MyList(r)
20 
21 
22 L1 = MyList([1,2,3])
23 L2 = MyList([4,5,6])
24 L3 = L1.myadd(L2)
25 print("L1=",L1)
26 print("L2=",L2)
27 #L3 = L1 + L2
28 print(L3) #MyList([1, 2, 3, 4, 5, 6])
View Code
 1 class MyList:
 2 
 3     def __init__(self, a):
 4         self.data = a.copy()
 5 
 6     def infos(self):
 7         return "MyList(" + str(self.data) + ")"
 8 
 9     def __str__(self):
10         return self.infos()
11 
12     def myadd(self,other):
13         r = []
14         r.extend(self.data)
15         r.extend(other.data)
16         #self.data.clear()   #L1 = MyList([])
17         #other.data.clear()  #L2 = MyList([])
18         return MyList(r)
19 
20     def __add__(self, other):
21         return self.myadd(other)
22 
23 
24 L1 = MyList([1,2,3])
25 L2 = MyList([4,5,6])
26 #L3 = L1.myadd(L2)
27 L3 = L1 + L2
28 print("L1=",L1)
29 print("L2=",L2)
30 print(L3) #MyList([1, 2, 3, 4, 5, 6])
View Code
 1 class MyList:
 2 
 3     def __init__(self, a):
 4         self.data = a.copy()
 5 
 6     def infos(self):
 7         return "MyList(" + str(self.data) + ")"
 8 
 9     def __str__(self):
10         return self.infos()
11 
12     def myadd(self,other):
13         r = []
14         r.extend(self.data)
15         if type(other) == int:
16             r.append(other)
17         elif type(other) == MyList:
18             r.extend(other.data)
19         else:
20             raise ValueError("other 不能出现其他值")
21         #self.data.clear()   #L1 = MyList([])
22         #other.data.clear()  #L2 = MyList([])
23         return MyList(r)
24 
25     def __add__(self, other):
26         return self.myadd(other)
27 
28 
29 L1 = MyList([1,2,3])
30 L2 = MyList([4,5,6])
31 #L3 = L1.myadd(L2)
32 L3 = L1 + L2
33 print("L1=",L1)
34 print("L2=",L2)
35 print(L3) #MyList([1, 2, 3, 4, 5, 6])
36 L3 = L1 + 10  #追加一个值
37 print(L3)  #MyList([1, 2, 3, 10])
View Code
 1 class MyList:
 2 
 3     def __init__(self, a):
 4         self.data = a.copy()
 5 
 6     def infos(self):
 7         return "MyList(" + str(self.data) + ")"
 8 
 9     def __str__(self):
10         return self.infos()
11 
12     #def myadd(self,other):
13     #    r = []
14     #    r.extend(self.data)
15     #    if type(other) == int:
16     #        r.append(other)
17     #    elif type(other) == MyList:
18     #        r.extend(other.data)
19     #    else:
20     #        raise ValueError("other 不能出现其他值")
21     #    #self.data.clear()   #L1 = MyList([])
22     #    #other.data.clear()  #L2 = MyList([])
23     #    return MyList(r)
24 
25     def __add__(self, other):
26         return self.myadd(other)
27 
28     def __mul__(self, rhs):  #right hand side
29         return MyList(self.data * rhs)
30         #以下方法可以实现
31         #L0 = MyList([])
32         #for x in range(rhs):
33         #    L0 += MyList(self.data)
34         #return L0
35 
36 L1 = MyList([1,2,3])
37 L2 = MyList([4,5,6])
38 L3 = L1 * 3
39 print(L3) #MyList([1, 2, 3, 1, 2, 3, 1, 2, 3])
View Code

 

 

反向算数运算符重载;

+              __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
 1 class MyList:
 2 
 3     def __init__(self, a):
 4         self.data = a.copy()
 5 
 6     def __str__(self):
 7         return "MyList("+ str(self.data) +")"
 8 
 9     def __mul__(self, rhs):  #right hand side
10         return MyList(self.data * rhs)
11 
12     def __rmul__(self, lhs): #
13         #return MyList(self.data * lhs)
14         #return self * lhs
15         return self.__mul__(lhs)
16 
17 
18 L1 = MyList([1,2,3])
19 L2 = MyList([4,5,6])
20 L3 = 3 * L1
21 print(L3) #MyList([1, 2, 3, 1, 2, 3, 1, 2, 3])
View Code

 

复合赋值运算符:

 __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

 

 1 class MyList:
 2     def __init__(self,a):
 3         self.data = a.copy()
 4 
 5     def __str__(self):
 6         return "MyList("+ str(self.data) +")"
 7 
 8     def __mul__(self, rhs):  #right hand side
 9         print("__mul__")
10         return MyList(self.data * rhs)
11 
12     def __imul__(self, rhs):
13         print("__imul__")
14         self.data = self.data * rhs
15         return self
16 
17 L1 = MyList([1,2,3])
18 L1 *= 2
19 print(L1)
20 #__mul__
21 #MyList([1, 2, 3, 1, 2, 3])
View Code

 一元运算符的重载:

__neg__      -(负号)

__pos__      +(正号)

__invert__   ~(取反)

重载方法:

def  __xxx__(self):

       ....

 1 class MyList:
 2 
 3     def __init__(self, a):
 4         self.data = a.copy()
 5 
 6     def __str__(self):
 7         return "MyList("+ str(self.data) +")"
 8 
 9     def __neg__(self):
10         ml = MyList(self.data)
11         for i in range(len(ml.data)):
12             ml.data[i] = -ml.data[i]
13         return ml
14 
15 
16 L1 = MyList([1,2,3])
17 L3 = -L1
18 print(L3) #MyList([-1, -2, -3])
View Code
 1 class MyList:
 2 
 3     def __init__(self, a):
 4         self.data = a.copy()
 5 
 6     def __str__(self):
 7         return "MyList("+ str(self.data) +")"
 8 
 9     def __invert__(self):
10         ml = MyList(self.data)
11         ml.data.reverse()
12         return ml
13 
14 
15 L1 = MyList([1,2,3])
16 L3 = ~L1
17 print(L3) #MyList([3, 2, 1])
View Code

 

比较运算符的重载:

__lt__      <  小于
__le__    <= 

__gt__    >

__ge__   >=

__eq__   ==

__ne__  !=

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

 1 class Tree:
 2     def __init__(self, h): #h 树的高度
 3         self.height = h
 4 
 5     def show(self):
 6         "描述"
 7         print(" * ")
 8         print("***")
 9         print(" * ")
10         print(" * ")
11 
12     def __lt__(self, rhs):
13         print("__lt__")
14         return self.height < rhs.height
15 
16     def __le__(self,rhs):
17         print("__le__")
18         return self.height < rhs.height
19 
20     def __gt__(self, rhs):
21         return not (self <= rhs)
22 
23 t1 = Tree(5)
24 t2 = Tree(10)
25 if t1 < t2:
26     print("t2树高")
27 else:
28     print("t1树高")
29 print(t1 <= t2)
30 print(t1 > t2)
View Code

 

 位运算符重载

__invert__   ~取反

__and__      &位与

__or__         |  位或

__xor__       ^ 位异或

__lshift__     <<   左移

__rshift__     >>    右移

内建函数的重载:

__abs__      abs(obj)         函数调用

__len__       len(obj)          

__reversed__     reversed(obj)

__round__         round(obj)

 

 1 class MyList:
 2 
 3     def __init__(self, a):
 4         self.data = a.copy()
 5 
 6     def __str__(self):
 7         return "MyList("+ str(self.data) +")"
 8 
 9     def __abs__(self):
10         temp = self.data.copy()   #列表
11         for i in range(len(temp)):
12             if temp[i] < 0:
13                 temp[i] = -temp[i]
14         return MyList(temp)
15 
16 
17 L1 = MyList([1,-2,3,-4])
18 L2 = abs(L1)
19 print(L2) #MyList([1, 2, 3, 4])
View Code

 

 

repr()   __repr__

str()   _str__

__add__   self + other

__radd__   other + self

__iadd__   self += other

 

posted on 2018-05-25 22:27  微子天明  阅读(225)  评论(0编辑  收藏  举报

导航