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)