larken

勤奋的人生才有价值

导航

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)

 

posted on 2019-03-18 17:11  larken  阅读(200)  评论(0编辑  收藏  举报