Python面向对象
1 1 # (1)定义类:在PPython中可以使用class来创建一个专门类 2 2 class Acount: 3 3 pass 4 4 def account(name,number,balance): 5 5 aact=Acount() 6 6 aact.name=name 7 7 aact.number=number 8 8 acct.balance=balance 9 9 return aact 10 10 def deposit(acct,amount): 11 11 if amount <= 0: 12 12 print("存款金额不得为负") 13 13 else: 14 14 acct.balance +=amount 15 15 def withdrow(acct,amount): 16 16 if amount <= 0: 17 17 print("余额不足") 18 18 else: 19 19 acct.balance -= amount 20 20 def desc(acct): 21 21 return "Account('{name}','{number}',{balance})".format(name=acct.name,number=acct.number,balance=acct.balance) 22 22 23 23 # (2-1) 定义__init__方法:在Python中,对象方法的第一个参数一定是对象本身 24 24 class Amount: 25 25 def __int__(self,name,number,balance): 26 26 self.name=name 27 27 self.number=number 28 28 self.balance=balance 29 29 # (2-2)定义__str__()方法 30 30 class Account: 31 31 def __str__(self): 32 32 return "Account('{name}','{number}',{balance})".format(name=self.name,number=self.number,balance=self.balance) 33 33 34 34 # (3)定义内部属性:如果想要避免用户字节的误用,那么可以使用self.__XXX的方法定义内部值域 35 35 class Account: 36 36 def __int__(self,name,number,balance): 37 37 self.__name=name 38 38 self.__numner=number 39 39 self.__balance=balance 40 40 # (4)定义外部属性:可以考虑在这类方法上加注@property 41 41 class Account: 42 42 def __int__(self,name,number,balance): 43 43 self.__name=name 44 44 self.__numner=number 45 45 self.__balance=balance 46 46 @property 47 47 def name(self): 48 48 return self.__name 49 49 # (5)静态方法与类方法 50 50 # 标注 @staticmethod:虽然可以通过实例来调用@staticmethod标注,但是建议通过类名来调用,明确让类名称作为静态方法的命名空间 51 51 class Accoutn: 52 52 @staticmethod 53 53 def default(name,number): 54 54 return Acount(name,number,100) 55 55 # 标注@classmethod:类中的方法如果标注了@classmethod,那么第一个参数一定是接受所在类的type实例 56 56 class Account: 57 57 @classmethod 58 58 def default(clz,name,number): 59 59 return clz(name,numberm,100) 60 60 61 61 # (6)定义运算符 62 62 class Rational: 63 63 def __init__(self,numer,denom): 64 64 self.numer=numer 65 65 self.denom=denom 66 66 def __add__(self, other): 67 67 return Rational(self.numer*other.denom+other.numer*self.denom,self.denom*other.denom) 68 68 def __sub__(self, other): 69 69 return Rational(self.numer*other.denom-other.numer*self.denom,self.denom*other.denom) 70 70 def __mul__(self, other): 71 71 return Rational(self.numer*other.numer,self.denom*other.denom) 72 72 def __truediv__(self, other): 73 73 return Rational(self.numer * other.denom, self.denom * other.denom) 74 74 def __str__(self): 75 75 return '{numer}/{denom}'.format(numer=self.numer,denom=self.denom) 76 76 def __repr__(self): 77 77 return 'Rational({numer},{denom})'.format(numer=self.numer,denom=self.denom) 78 78 r1=Rational(1,2) 79 79 r2=Rational(2,3) 80 80 print(r1+r2) 81 81 print(r1-r2) 82 82 print(r1*r2) 83 83 print(r1/r2) 84 84 85 85 # (7)__new__(), __init__(),__del__() 86 86 # __init__()是在类的实例构建之后进行初始化的方法,类的实例如何构建实际上是由__new__()来定义。 87 87 # __new__()方法的第一个参数是类本身,之后可定义任何参数作为构建对象之用。 88 88 # __new__()方法可以返回对象,如果返回的对象是第一个参数的类实例,接下来就会执行__init__()方法,__init__()方法的第一个参数就是__new__()返回的对象。 89 89 # __new__()如果没有返回第一个参数的类实例(返回别的实数或None),就不会执行__init__()方法. 90 90 class Some: 91 91 def __new__(cls, isClsInstance): 92 92 print("__new__") 93 93 if isClsInstance: 94 94 return object.__new__(cls) 95 95 def __init__(self,isClsInstance): 96 96 print('__init__') 97 97 print(isClsInstance) 98 98 Some(True) 99 99 Some(False) 100 100 # __new__()如果返回第一个参数的类实例,就会执行__init__()方法,借助定义__new__()方法就可以决定如何构建对象与初始化对象,一个应用例子如下: 101 101 class Logger: 102 102 __loggers={} #保存已创建的Logger实例 103 103 def __new__(cls, name): 104 104 if name not in cls.__loggers: #如果字典中不存在对应的Logger就创建 105 105 logger=object.__new__(cls) 106 106 cls.__loggers[name]=logger 107 107 return logger 108 108 return cls.__loggers[name] #否则返回字典中对应的Logger实例 109 109 def __init__(self,name): 110 110 #为了不重复设置Logger实例属性,使用vars(self)获取Logger实例上的属性列表 111 111 if name not in vars(self): 112 112 self.name=name #设置Logger的名称 113 113 def log(self,message): #简单模拟日志的行为 114 114 print('{name}:{message}'.format(name=self.name,message=message)) 115 115 logger1=Logger('xlogging') 116 116 logger1.log('一些日志信息') 117 117 logger2=Logger('xlogging') 118 118 logger2.log('另外一些日志信息') 119 119 logger3=Logger('xlog') 120 120 logger3.log('再来一些日志信息') 121 121 print(logger1==logger2) 122 122 print(logger2==logger3) 123 123 # 如果想在对象被删除时自行定义一些清楚相关资源的操作,可以做执行__del__()方法 124 124 class Some: 125 125 def __del__(self): 126 126 print('__del__') 127 127 s=Some() 128 128 s=None 129 129 130 130 # (8)类的继承:类名称旁边多了个括号,并指定了类,这在Python中代表这继承该类 131 131 class Role: 132 132 def __init__(self,name,level,blood): 133 133 self.name=name 134 134 self.level=level 135 135 self.blood=blood 136 136 def __str__(self): 137 137 return "('{name}',{level},{blood})".format(**vars(self)) 138 138 def __repr__(self): 139 139 return self.__str__() 140 140 class SwordMan(Role): 141 141 def fight(self): 142 142 print('挥剑攻击') 143 143 class Magician(Role): 144 144 def fight(self): 145 145 print('魔法攻击') 146 146 def cure(self): 147 147 print('魔法治疗') 148 148 # 鸭子类型:思考对象的行为,而不是对象的种类。按此苏伟设计的程序,会有比较高的通用性。 149 149 def draw_fight(role): 150 150 print(role,end='') 151 151 role.fight() 152 152 swordsman=SwordMan('Justin',1,200) 153 153 draw_fight(swordsman) 154 154 magician=Magician('Monica',1,100) 155 155 draw_fight(magician) 156 157 # (9)创建ABC(抽象基类) 158 from abc import ABCMeta,abstractmethod 159 class Ordering(metaclass=ABCMeta): 160 # 在这里使用@abstractmethod标注不是必要的,使用@abstractmethod标注具有提醒的作用 161 @abstractmethod 162 def __eq__(self, other): 163 pass 164 @abstractmethod 165 def __gt__(self, other): 166 pass 167 def __ge__(self, other): 168 return self > other or self == other 169 def __lt__(self, other): 170 return not(self > other and self == other) 171 def __le__(self, other): 172 return (not self >= other) or self ==other 173 def __ne__(self, other): 174 return not self ==other 175 class Ball(Ordering): #继承Ordering 176 def __init__(self,radius): 177 self.radius=radius 178 def __eq__(self, other): # 实现__eq__()与__gt__() 179 return hasattr(other,'radius') and self.radius == other.radius 180 def __gt__(self, other): 181 return hasattr(other,'radius') and self.radius > other.radius 182 b1=Ball(10) 183 b2=Ball(20) 184 print(b1 > b2) 185 print(b1 <= b2) 186 print(b1 == b2)