Chapter 2: The Singleton Pattern
The Problem
- Debugging methods: From simply printing to write log to a file
- DRY principle: don't repeat yourself
Enter the project
- step 1:
def write_log(level, msg):
with open("/var/log/filename.log", "a") as log_file:
log_file.write("[{0}] {1}\n".format(level, msg))
def critical(msg):
write_log("CRITICAL",msg)
def error(msg):
write_log("ERROR", msg)
def warn(msg):
write_log("WARN", msg)
def info(msg):
write_log("INFO", msg)
def debug(msg):
write_log("DEBUG", msg)
- step 2:
class Logger(object):
"""A file-based message logger with the following properties
Attributes:
file_name: a string representing the full path of the log file to which this logger will write its messages
"""
def __init__(self, file_name):
"""Return a Logger object whose file_name is *file_name*"""
self.file_name = file_name
def _write_log(self, level, msg):
"""Writes a message to the file_name for a specific Logger instance"""
with open(self.file_name, "a") as log_file:
log_file.write("[{0}] {1}\n".format(level, msg))
def critical(self, level, msg):
self._write_log("CRITICAL",msg)
- step 3:
class SingletonObject(object):
class __SingletonObject():
def __init__(self):
self.val = None
def __str__(self):
return "{0!r} {1}".format(self, self.val)
# followed by function above
instance = None
def __new__(cls):
if not SingletonObject.instance:
SingletonObject.instance = SingletonObject.__SingletonObject()
return SingletonObject.instance
def __getattr__(self, name):
return getattr(self.instance, name)
def __setattr__(self, name):
return setattr(self.instance, name)
str() used for print
new(cls) used for instance cls为传递的类
getattr()
setattr()
https://zhuanlan.zhihu.com/p/21379984
https://juejin.im/post/5add4446f265da0b8d4186af
总结来说new是class方法,init是对象方法
简单来写:
class Singleton(object):
_instance = None
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = object.__new__(cls)
return cls._instance
s1 = Singleton()
s2 = Singleton()
print(s1)
print(s2)
工厂模式:
class Fruit(object):
def __init__(self):
pass
def print_color(self):
pass
class Apple(Fruit):
def __init__(self):
pass
def print_color(self):
print("apple is in red")
class Orange(Fruit):
def __init__(self):
pass
def print_color(self):
print("orange is in orange")
class FruitFactory(object):
fruits = {"apple": Apple, "orange": Orange}
def __new__(cls, name):
if name in cls.fruits.keys():
return cls.fruits[name]()
else:
return Fruit()
fruit1 = FruitFactory("apple")
fruit2 = FruitFactory("orange")
fruit1.print_color()
fruit2.print_color()
https://stackoverflow.com/questions/674304/why-is-init-always-called-after-new
Tradeoff
Using the global state should be avoided
Chapter 3: The Prototype Pattern
Shallow Copy
a = range(1, 6)
b = a[:]
Deep Copy
from copy import deepcopy
lst2 = deepcopy(lst1)
网友评论