Python デザインパターン サンプルコード Flyweight
Mark Summerfield『実践 Python 3』デザインパターンのサンプルコード
Python3(3.11)で動くソースコード(.pyファイル .ipynbファイル)あります
「anaconda3」on .py「PyCharm」.ipynb「Jupyter Notebook」
(2023-11-17)Python3.11で動作確認済み
コードを追加「time.clock = time.time」
旧いモジュールがなくなったので新しい互換モジュールを変換して,旧いプログラムをそのまま使えるようにした。
Point (__slots__, __repr__)【pointstore2.py】
Point (__slots__, __key, __getattr__, __setattr__, __repr__)
'1F5A886E150:x', (0, 5) '1F5A886E150:y', (512, 5) '1F5A886E150:z', (1024, 5) '1F5A886E150:color', (1536, 4)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51
#!/usr/bin/env python3 # Copyright c 2012-13 Qtrac Ltd. All rights reserved. # This program or module is free software: you can redistribute it # and/or modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. It is provided for # educational purposes and is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. import sys import time def main(): regression = False size = int(1e6) if len(sys.argv) > 1 and sys.argv[1] == "-P": regression = True size = 20 start = time.clock() points = [] for i in range(size): points.append(Point(i, i ** 2, i // 2)) end = time.clock() - start assert points[size - 1].x == size - 1 assert points[size - 1].color is None print(len(points)) if not regression: # wait until we can see how much memory is used print("took {} secs to create {:,} points".format(end, size)) input("press Enter to finish") class Point: __slots__ = ("x", "y", "z", "color") def __init__(self, x=0, y=0, z=0, color=None): self.x = x self.y = y self.z = z self.color = color def __repr__(self): return "Point({0.x!r}, {0.y!r}, {0.z!r}, {0.color!r})".format(self) if __name__ == "__main__": main()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72
#!/usr/bin/env python3 # Copyright c 2012-13 Qtrac Ltd. All rights reserved. # This program or module is free software: you can redistribute it # and/or modify it under the terms of the GNU General Public License as # published by the Free Software Foundation, either version 3 of the # License, or (at your option) any later version. It is provided for # educational purposes and is distributed in the hope that it will be # useful, but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU # General Public License for more details. import atexit import os import shelve import sys import tempfile import time import Qtrac def main(): regression = False size = int(1e6) if len(sys.argv) > 1 and sys.argv[1] == "-P": regression = True size = 20 Qtrac.remove_if_exists(os.path.join(tempfile.gettempdir(), "point.db")) start = time.clock() points = [] for i in range(size): points.append(Point(i, i ** 2, i // 2)) end = time.clock() - start assert points[size - 1].x == size - 1 print(len(points)) if not regression: # wait until we can see how much memory is used print("took {} secs to create {:,} points".format(end, size)) input("press Enter to finish") class Point: __slots__ = () __dbm = shelve.open(os.path.join(tempfile.gettempdir(), "point.db")) def __init__(self, x=0, y=0, z=0, color=None): self.x = x self.y = y self.z = z self.color = color def __key(self, name): return "{:X}:{}".format(id(self), name) def __getattr__(self, name): return Point.__dbm[self.__key(name)] def __setattr__(self, name, value): Point.__dbm[self.__key(name)] = value def __repr__(self): return "Point({0.x!r}, {0.y!r}, {0.z!r}, {0.color!r})".format(self) atexit.register(__dbm.close) if __name__ == "__main__": main()
29 30 31 32 33 34 35 36 37 38 39 40 41
if sys.version_info[:2] < (3, 3): def remove_if_exists(filename): try: os.remove(filename) except OSError as err: if err.errno != errno.ENOENT: raise else: def remove_if_exists(filename): try: os.remove(filename) except FileNotFoundError: pass # All other exceptions are passed to the caller