1 # -*- coding: utf-8 -*-
2 # 创建学生类
3 class Student(object):
4
5 def __init__(self, name, score):
6 self.__name = name
7 self.__score = score
8 def print_score(self):
9 print('%s:%s' % (self.__name, self.__score))
10
11 def get_grade(self):
12 if self.__score >= 90:
13 return 'A'
14 elif self.__score >= 60:
15 return 'B'
16 else:
17 return 'C'
18
19 def set_score(self, score):
20 self.score = score
21 def get_score(self):
22 return self.__score
23
24 # def run(self):
25 # print('student is running...')
26
27 bart = Student('liuepgnfei', 99)
28 '''
29 bart.print_score()
30 print(bart.get_grade())
31
32 #bart.set_score(22)
33 #bart.print_score()
34
35 #print(bart.name)
36 #print(bart.score)
37 #print(Student)
38
39 #实际上是新增了一个__name变量
40 bart.__score = 88
41 print(bart.__score)
42 bart.print_score()
43 '''
44
45 #继承与多态
46 class Animal(object):
47 def run(self):
48 print('Animal is running...')
49
50 class Dog(Animal):
51
52 def run(self):
53 print('Dog is running..')
54 def eat(self):
55 print('Eating meat...')
56
57 class Cat(Animal):
58
59 def run(self):
60 print('Cat is running..')
61
62 dog = Dog()
63 cat = Cat()
64 '''
65 dog.run()
66 cat.run()
67
68 print(isinstance(dog, Animal))
69 print(isinstance(dog, Dog))
70
71
72 #传入一个student类也可以,只要有run()实现就行
73 def run_twice(a):
74 a.run()
75 a.run()
76
77 run_twice(dog)
78 ---------------------------------------------
79
80 #获取对象信息
81 str = 'love'
82 print(type(str))
83 print(type(dog))
84
85 import types
86 def fn():
87 pass
88
89 print(type(fn))
90 print(types.FunctionType)
91 print(types.BuiltinFunctionType)
92 print(types.LambdaType)
93 print(types.GeneratorType)
94
95 print(isinstance(dog, Dog))
96 print(isinstance('a', str))
97
98 print(dir('ABC'))
99 print(dir('ABC').__len__())
100 print('ABC'.__len__())
101
102
103 class MyObject(object):
104 def __init__(self):
105 self.__x = 9
106 def power(self):
107 return self.__x * self.__x
108 obj = MyObject()
109
110 print(hasattr(obj,'x'))
111 print(hasattr(obj,'y'))
112 print(setattr(obj,'y', 19))
113 print(getattr(obj,'y'))
114
115 print(obj.y)#??
116
117 fn = getattr(obj, 'power')
118 print(fn)
119 print(fn())
120
121 class Student(object):
122 count = 0
123
124 def __init__(self, name):
125 self.name = name
126 Student.count += 1
127
128 print(Student("lilei").count)
129 print(Student("lilei").count)
130 print(Student("lilei").count)
131 print(Student("lilei").count)
132 '''
133
134 #########
135 #面向对象高级编程
136 #########
137
138 #1、使用__slots__
139 '''
140 class Student(object):
141 pass
142
143 s=Student()
144 s.name = "Mike"
145 print(s.name)
146
147 def set_age(self, age):
148 self.age=age
149
150 #为对象绑定方法
151 from types import MethodType
152 s.set_age = MethodType(set_age, s)
153 s.set_age(25)
154 print(s.age)
155
156 #s2.set_age(20)
157
158 #为类绑定方法
159 def set_score(self, score):
160 self.score = score
161
162 #此时可理解绑定方法时,对应的绑定了score属性
163 Student.set_score = set_score
164
165 s2 = Student()
166 s2.set_score(100)
167 print(s2.score)
168 '''
169 '''
170 方法的绑定存在作用域的限制,类似于c语言中变量作用域
171 需要说明的是,即使绑定了方法,如果没有通过实例调用,
172 被绑定方法中的属性仍然未绑定至类对象中
173 '''
174 '''
175 class Student(object):
176 __slots__ = ('name', 'age')
177
178 s = Student()
179 s.name = 'Mike'
180 s.age = 20
181 print(s.age)
182
183 #子类中定义__slots__,以继承父类中的属性限制
184 class stu(Student):
185 __slots__ = ('score')
186
187 s2 = stu()
188
189 s2.age = 2
190 print(s2.age)
191 s2.score = 20
192 print(s2.score)
193 '''
194
195 '''
196 class Student(object):
197 def get_score(self):
198 return self._score
199
200 def set_score(self, value):
201 if not isinstance(value, int):
202 raise ValueError('score must be an intrger!')
203 if not (0 <= value <= 100):
204 raise ValueError('score must between 0~100!')
205 self._score = value
206
207 s = Student()
208 s.set_score(100)
209 #s.set_score(1000)
210 '''
211 '''
212 #使用装饰器
213 class Student(object):
214
215 #property:python内置装饰器,把一个方法变成属性调用
216 @property
217 def score(self):
218 print("getter()")
219 return self._score
220
221 #定义setter属性
222 @score.setter
223 def score(self, value):
224 if not isinstance(value, int):
225 raise ValueError('score must be an integer!')
226 if not (0 <= value <= 100):
227 raise ValueError('score must between 0~100!')
228 self._score = value
229 print("setter()")
230
231 s=Student()
232
233 import sys
234 print(sys._getframe().f_lineno)
235 #类似于方法绑定,只有调用setter绑定后,才存在width属性
236 #只定义@property,意味着width的getter成为类的属性,而只有定义了setter,
237 #并调用后,_width才成为类的属性
238 s.score = 60
239
240 print(sys._getframe().f_lineno)
241 s.score
242
243
244 class Screen(object):
245 @property
246 def width(self):
247 return self._width
248 @width.setter
249 def width(self, value):
250 self._width = value
251
252 @property
253 def height(self):
254 return self._height
255 @height.setter
256 def height(self, value):
257 self._height = value
258
259 @property
260 def resolution(self):
261 return self._height*self._width
262
263 s = Screen()
264 s.width = 1024
265 s.height = 768
266 print('resolution =', s.resolution)
267 if s.resolution == 786432:
268 print('测试通过!')
269 else:
270 print('测试失败!')
271
272 '''
273 '''
274 #3、多重继承
275
276 class Animal(object):
277 pass
278
279 class Mammal(object):
280 pass
281
282 class Runnable(object):
283 def run(self):
284 print('Running...')
285
286 class Flyable(object):
287 def fly(self):
288 print('Flying...')
289
290 #Dog多重继承了Mammal、Runnable
291 class Dog(Mammal, Runnable):
292 pass
293 class Bat(Mammal, Flyable):
294 pass
295 '''
296 #MixIn
297 #python中会对多继承的类名后面添加MixIn,例如RunnableMinIn.
298 #这并不影响功能,但是会告诉读代码的人,这个类是一个MinIn类,
299 #该类是作为功能添加到子类中,并不是父类,作用等同于java中的interface
300
301 '''
302 #4、定制类
303 #__str__():返回用户看到的字符串
304 #__repr__():返回开发者看到的字符串
305 class Student(object):
306 def __init__(self, name):
307 self.name = name
308 def __str__(self):
309 return 'Student object (name:%s)' % self.name
310 __repr__ = __str__
311
312 print(Student("Mike"))
313
314 s = Student('Jane')
315 #命令行模式下直接执行s
316 s
317 '''
318
319 #__iter__:该方法返回一个迭代对象,然后,Python的for循环就会不断
320 #调用该迭代对象的__next__()方法拿到循环的下一个值,直到遇到
321 #StopIteration错误时退出循环。
322 #说明:首次调用执行__iter__(),随后调用执行__next__()
323
324 #__getitem__:该方法可以使实例像list那样取第n个元素
325 #__setitem__:把对象视作list或dict来对集合复制
326 #__delitem__:用于删除某个元素
327 '''
328 class Fib(object):
329 def __init__(self):
330 self.a, self.b = 0, 1
331 def __iter__(self):
332 return self
333 def __next__(self):
334 self.a, self.b = self.b, self.a + self.b
335 if self.a > 100000:
336 raise StopIteration()
337 return self.a
338
339 def __getitem__(self, n):
340 if isinstance(n, int):#n是索引
341 a, b = 1, 1
342 for x in range(n):
343 a, b = b, a+b
344 return a
345
346 if isinstance(n, slice):#n是切片
347 start = n.start
348 stop = n.stop
349 if start is None:
350 start = 0
351 a, b = 1, 1
352 L = []
353 for x in range(stop):
354 if x >= start:
355 L.append(a)
356 a, b = b, a + b
357 return L
358
359 for n in Fib():
360 print(n)
361
362
363 f = Fib()
364 print(f[0])
365 print(f[1])
366 print(f[2])
367 print(f[3])
368
369 #切片
370 print(f[:100])
371 '''
372 '''
373 #__getattr__:动态返回一个属性;当不存在attr属性时,才会调用__getattr__()
374 #当__getattr__()也不存在时,默认返回None
375 class Student(object):
376 def __init__(self):
377 self.name = 'Mike'
378
379 def __getattr__(self, attr):
380 if attr == 'score':
381 return 99
382 raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)
383
384 s=Student()
385 print(s.abc)
386
387
388 class Chain(object):
389 def __init__(self, path=''):
390 self._path = path
391 def __getattr__(self, path):
392 # return Chain('%s' % (self._path))
393 # return Chain('%s' % (path))
394 return Chain('%s/%s' % (self._path, path))
395 def __str__(self):
396 return self._path
397
398 print(Chain().status.user.timeline.list)
399
400 #__call__:直接在实例本身上调用实例方法
401 class Student(object):
402 def __init__(self, name):
403 self.name = name
404 def __call__(self):
405 print("My name is %s." % self.name)
406
407 s = Student('Mike')
408 s()
409
410 #通过callable()函数,可以半段一个对象是否是‘可调用’对象
411 print(callable(Student))
412 '''
413 #更多的定制方法见python官方文档
414 #https://docs.python.org/3/reference/datamodel.html#special-method-names
415
416 #4、使用枚举类
417 #from enum import Enum, unique
418 #Month类型的枚举类
419 '''
420 Month = Enum('Month', ('Jan', 'Feb', 'Mar'))
421 for name, member in Month.__members__.items():
422 # print(name, '=>', member, ',', member.value)
423 print(member)
424 print(member.name)
425 print(member.value)
426 '''
427 '''
428 @unique #此装饰器可帮助我们检查保证没有重复值
429 class Weekday(Enum):
430 Sun = 0
431 Mon = 1
432 Tue = 2
433 Wed = 3
434 Thu = 4
435 Fri = 5
436 Sat = 6
437
438 day1 = Weekday.Mon
439 print(day1)
440 print(Weekday.Tue)
441 print(Weekday.Wed.value)
442
443 for name, member in Weekday.__members__.items():
444 print(name, '=>', member)
445
446 class Gender(Enum):
447 Male = 0
448 Female = 1
449
450 class Student(object):
451 def __init__(self, name, gender):
452 self.name = name
453 self.gender = gender
454
455 bart = Student('Bart', Gender.Male)
456 if bart.gender == Gender.Male:
457 print('测试通过!')
458 else:
459 print('测试失败!')
460 '''
461 #5、使用元类
462 '''
463 class Hello(object):
464 def hello(self, name='world'):
465 print("Hello, %s." % name)
466
467 from hello import Hello
468 h=Hello()
469 h.hello()
470
471 #使用type()动态创建类
472 def fn(self, name='world'):
473 print('Hello, %s.' % name)
474
475 Hello = type('Hello', (object,), dict(hello=fn))
476 h=Hello()
477 h.hello()
478 print(type(Hello))
479 print(type(h))
480
481
482 class ListMetaclass(type):
483 def __new__(cls, name, bases, attrs):
484 attrs['add'] = lambda self, value:self.append(value)
485 return type.__new__(cls, name, bases, attrs)
486
487 class MyList(list, metaclass=ListMetaclass):
488 pass
489
490 L = MyList()
491 L.add(1)
492 print(L)
493 '''
494
495 class Field(object):
496
497 def __init__(self, name, column_type):
498 self.name = name
499 self.column_type = column_type
500
501 def __str__(self):
502 return '<%s:%s>' % (self.__class__.__name__, self.name)
503
504
505 class StringField(Field):
506
507 def __init__(self, name):
508 super(StringField, self).__init__(name, 'varchar(100)')
509
510 class IntegerField(Field):
511
512 def __init__(self, name):
513 super(IntegerField, self).__init__(name, 'bigint')
514
515 class ModelMetaclass(type):
516
517 def __new__(cls, name, bases, attrs):
518 if name=='Model':
519 return type.__new__(cls, name, bases, attrs)
520 print('Found model: %s' % name)
521 mappings = dict()
522 for k, v in attrs.items():
523 if isinstance(v, Field):
524 print('Found mapping: %s ==> %s' % (k, v))
525 mappings[k] = v
526 for k in mappings.keys():
527 attrs.pop(k)
528 attrs['__mappings__'] = mappings # 保存属性和列的映射关系
529 attrs['__table__'] = name # 假设表名和类名一致
530 return type.__new__(cls, name, bases, attrs)
531
532 class Model(dict, metaclass=ModelMetaclass):
533
534 def __init__(self, **kw):
535 super(Model, self).__init__(**kw)
536
537 def __getattr__(self, key):
538 try:
539 return self[key]
540 except KeyError:
541 raise AttributeError(r"'Model' object has no attribute '%s'" % key)
542
543 def __setattr__(self, key, value):
544 self[key] = value
545
546 def save(self):
547 fields = []
548 params = []
549 args = []
550 for k, v in self.__mappings__.items():
551 fields.append(v.name)
552 params.append('?')
553 args.append(getattr(self, k, None))
554 sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params))
555 print('SQL: %s' % sql)
556 print('ARGS: %s' % str(args))
557
558 class User(Model):
559 # 定义类的属性到列的映射:
560 id = IntegerField('id')
561 name = StringField('username')
562 email = StringField('email')
563 password = StringField('password')
564
565 u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
566 u.save()