1. 概念
原型模式是一种创建型设计模式,它通过复制(克隆)现有对象来创建新对象。这样可以避免使用复杂的构造函数来创建对象,提高程序的性能和可维护性。
2. 功能
原型模式的功能是通过复制现有对象来创建新对象,从而提高程序的性能和可维护性。
3. 优点
4. 缺点
5. 应用场景
6. 使用方式
在 Python 中,可以通过实现 __copy__()
和 __deepcopy__()
方法来实现原型模式。其中,__copy__()
方法用于浅拷贝,__deepcopy__()
方法用于深拷贝。
在 Python 中,许多内置的数据类型和标准库中的对象都实现了原型模式,如:字典、列表、集合、datetime 对象等。在自己的代码中,我们也可以使用原型模式来减少代码的量,提高程序的性能。特别是在需要创建大量相似对象的场景中,使用原型模式可以帮助我们大大提高效率。
原型模式是一种设计模式,它允许我们通过复制现有的对象来创建新的实例。在 Python 中,原型模式可以通过 copy
模块中的 copy()
和 deepcopy()
函数来实现。
下面是一个简单的例子,说明如何使用原型模式创建新的对象:
我们定义了一个 Person
类,该类有一个 clone()
方法,该方法使用 deepcopy()
函数来复制 Person
对象并返回一个新的实例。此外,该方法还接受一个可选的 kwargs
参数,该参数是一个字典,可以用来更新新的对象的属性。
现在,我们可以创建 Person
对象,并使用 clone()
方法创建一个新的实例。例如:
import copy
class Person():
def __init__(self, name, age):
self.name = name
self.age = age
# 使用 print() 函数或字符串格式化操作符 % 将对象打印为字符串时,实际上是调用了该对象的 __str__() 方法
def __str__(self): # __str__() 用于返回类的字符串表示形式
return 'Person(name={}, age={})'.format(self.name, self.age)
def clone(self, **kwargs):
print("*********开始克隆")
clone_obj = copy.deepcopy(self)
clone_obj.__dict__.update(kwargs)
return clone_obj
p1 = Person("Alice", 28)
p2 = p1.clone(name="Bob")
p3 = p1.clone(name="Charlie", age=30)
print(p1, p1.name, p1.age)
print(p2, p2.name, p2.age)
print(p3, p3.name, p3.age)
运行上述代码,输出结果为:
*********开始克隆
*********开始克隆
Person(name=Alice, age=28) Alice 28
Person(name=Bob, age=28) Bob 28
Person(name=Charlie, age=30) Charlie 30
从上面的输出结果可以看出,我们可以通过原型模式创建新的对象,并使用可选的参数来修改属性。这种模式非常适用于那些需要创建大量相似对象的场景,例如许多游戏中的敌人或NPC对象。
浅拷贝和深拷贝都是 Python 中用来复制对象的方式。
概念:
工作原理:
优点:
缺点:
使用场景:
Python 中实现浅拷贝和深拷贝的方式分别是 copy
和 deepcopy
方法。例如:
import copy
# a = [1,2]
a = [[1,2], [3,4]]
b = copy.copy(a)
print(a,b)
# b[1] = 3
b[1][1] = 5
print(a,b)
a = [[1,2], [3,4]]
b = copy.deepcopy(a)
print(a,b)
b[1][1] = 5
print(a,b)
运行结果:
[[1, 2], [3, 4]] [[1, 2], [3, 4]]
[[1, 2], [3, 5]] [[1, 2], [3, 5]]
[[1, 2], [3, 4]] [[1, 2], [3, 4]]
[[1, 2], [3, 4]] [[1, 2], [3, 5]]
__str__()
方法介绍在 Python 中,__str__()
方法是一种特殊的方法,用于返回类的字符串表示形式。当我们使用 print()
函数或字符串格式化操作符 %
将对象打印为字符串时,实际上是调用了该对象的 __str__()
方法。
通常情况下,__str__()
方法返回的字符串应该是可读性较好的字符串,方便人类阅读。比如,如果一个类 Person
表示一个人的信息,我们可以在该类中定义如下的 __str__()
方法:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __str__(self):
return 'Person(name={}, age={})'.format(self.name, self.age)
在上面的例子中,__str__()
方法返回了一个类似于 Person(name=Alice, age=28)
的字符串表示形式,表示该对象的名字和年龄信息。通过这种方式,我们可以方便地打印或记录对象的信息,便于开发和调试。
需要注意的是,__str__()
方法应该返回一个字符串类型的值,否则会抛出 TypeError
异常。
__init__(self)
方法介绍在 Python 中,__init__(self)
是一种特殊的方法,用于在创建一个新的对象时初始化该对象的属性。该方法在类中只能被定义一次,通常用于定义类的属性及其初始值。
在 Python 中,每次创建一个新的对象时,都会自动调用该对象所属类的 __init__(self)
方法进行初始化。在 __init__(self)
方法中,可以通过 self
参数来访问该对象的属性,从而给属性设置初始值。
例如,假设我们有一个类 Person
表示一个人的信息,可以在该类中定义如下的 __init__(self)
方法:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
在上面的例子中,__init__(self)
方法定义了两个参数 name
和 age
,并将它们分别赋值给了对象的 name
和 age
属性。在创建一个新的 Person
对象时,可以通过传递相应的参数来初始化该对象的属性,例如:
p1 = Person('Alice', 28)
p2 = Person('Bob', 30)
在上面的例子中,我们分别创建了两个 Person
对象,并传递了不同的参数,从而初始化了这两个对象的属性。
在 Python 中,del
是一种关键字,用于删除对象或对象属性。当使用 del
关键字时,它会执行对应对象的 __del__()
方法,方法内可以进行一些清理操作,通常在不再需要对象时使用。
使用 del
关键字可以删除一个对象,例如:
x = 10 # 创建一个整数对象
del x # 删除该对象
使用 del
关键字也可以删除一个对象的属性,例如:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
p = Person('Alice', 28)
del p.age # 删除 p 对象的 age 属性
在上面的例子中,我们先创建了一个 Person
对象 p
,然后使用 del
关键字删除了它的 age
属性。删除属性时不会影响对象本身的存在,只是将属性删除。
需要注意的是,在类中定义了 __del__()
方法并不能确保它会被立即执行。对于垃圾回收机制,Python 中的实现是引用计数机制,当一个对象的引用计数为 0 时,Python 会自动调用它的 __del__()
方法。但是,由于引用计数并不是完全准确的,因此 __del__()
方法可能会有延迟执行的情况,不能依赖它进行一些重要的操作。
在 Python 中,obj.__dict__
是一个字典,用于存储对象的属性和值。而 kwargs
则是一个字典,包含键值对,表示要更新的属性和值。
obj.__dict__.update(kwargs)
表示将 kwargs
字典中的键值对更新到 obj
对象的 __dict__
中。也就是说,使用 update()
方法可以动态地修改对象的属性值,这在某些情况下是非常有用的。
例如,在实例化对象的时候,如果需要动态地为对象设置属性,可以使用 __dict__
和 update()
方法,如下所示:
class Person:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
p = Person(name='Alice', age=28)
print(p.name) # 输出:Alice
print(p.age) # 输出:28
在上面的例子中,我们定义了一个 Person
类,可以接收任意数量的关键字参数。在实例化对象时,我们使用 __dict__
和 update()
方法将关键字参数更新到对象的 __dict__
中,从而动态地为对象设置属性。