Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/289.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/design-patterns/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中的原型模式_Python_Design Patterns_Prototype Pattern - Fatal编程技术网

Python中的原型模式

Python中的原型模式,python,design-patterns,prototype-pattern,Python,Design Patterns,Prototype Pattern,我在Python 2.7中实现了以下原型模式: def clone (instance): x = object.__new__ (type (instance)) x.__dict__ = dict (instance.__dict__) return x 这显然不适用于非新样式类(旧样式类?)和dict之类的内置类 有没有一种方法可以在Python2中清晰地将其扩展到可变的内置类型,如序列和映射类型?我认为您可以使用 deepcopy方法创建对象的1-1个副本: &

我在Python 2.7中实现了以下原型模式:

def clone (instance):
    x = object.__new__ (type (instance))
    x.__dict__ = dict (instance.__dict__)
    return x
这显然不适用于非新样式类(旧样式类?)和dict之类的内置类


有没有一种方法可以在Python2中清晰地将其扩展到可变的内置类型,如序列和映射类型?

我认为您可以使用

deepcopy
方法创建对象的1-1个副本:

>>> import copy
>>> x = [1,2,3]
>>> z = copy.deepcopy(x)
>>> x[0] = 3
>>> x
[3, 2, 3]
>>> z
[1, 2, 3]

我想你可以用

deepcopy
方法创建对象的1-1个副本:

>>> import copy
>>> x = [1,2,3]
>>> z = copy.deepcopy(x)
>>> x[0] = 3
>>> x
[3, 2, 3]
>>> z
[1, 2, 3]

你想做的是被误导了

如果您想要一份拷贝,只需使用
copy
deepcopy

如果您想要JavaScript样式的对象,请创建一个可以克隆的根类,或者更好地用Python而不是JavaScript重新思考代码

如果你想要功能齐全的JavaScript风格的克隆,即使是内置的,你也不能这样做

<>也要记住,在java和C++等非原型语言中使用原型模式的主要动机是(a)避免<代码>新< /CODE >对象的成本,以及(b)允许向不同实例添加不同的方法或属性。对于前者,您并没有避免成本,而且在Python中这也不重要。对于后者,在Python中向实例添加方法和属性已经很容易了,而克隆并没有以任何方式让它变得更容易


我知道,与其他内置类型相比,数字类型有一些不同之处

不,这里的区别不是数字与序列,而是不变类型与可变类型:

>>> id(tuple())
4298170448
>>> id(tuple())
4298170448
>>> id(tuple(()))
4298170448
>>> id(tuple([]))
4298170448
此外,它与
int
tuple
构造函数的花式无关。如果该值未缓存在任何位置,则即使是重复的文字每次都会获得一个新实例:

>>> id(20000)
4439747152
>>> id(20000)
4439747216
小整数、空元组和不可关联的魔法常量的值在启动时被预先缓存。短字符串通常会被拘留。但具体细节取决于实现


那么,这对你有什么影响

嗯,克隆不可变类型是毫无意义的。根据定义,它是同一事物的不可更改的复制品,那么这又有什么好处呢


同时,不使用
\uuuu dict\uuuu
存储的类型不能以这种方式克隆(无论它们是内置类型、使用插槽的类型、动态生成属性的类型等等)。在某些情况下,你会得到一个错误,在其他情况下,只是错误的行为

因此,如果通过“序列、映射和数字类型”包括内置的
int
list
、stdlib类型(如
Decimal
deque
)或常见的第三方类型(如
gmpy.mpz
blist.sortedct
),则此机制将不起作用


除此之外,即使可以克隆内置类,也不能向它们添加新属性:

>>> a = []
>>> a.foo = 3
AttributeError: 'list' object has no attribute 'foo'
所以,如果你让它工作,它也不会有任何用处


同时,调用
object.\uuuuuu new\uuuu
而不是
type(instance)。\uuuuu new\uuuu
可能会为不同的类带来各种问题。其中一些,如
\uuuu dict\uuuu
,会给您一个错误提示,但您不能在所有情况下都依赖于此


这个想法还有其他不太严重的问题。例如:

>>> class Foo(object):
...    def __init__(self):
...        self.__private = 3
>>> foo = Foo()
>>> foo.__private
3
>>> bar = clone(foo)
>>> bar.__private
AttributeError: 'Foo' object has no attribute '__private'
>>> bar._Foo__private
3

你想做的是被误导了

如果您想要一份拷贝,只需使用
copy
deepcopy

如果您想要JavaScript样式的对象,请创建一个可以克隆的根类,或者更好地用Python而不是JavaScript重新思考代码

如果你想要功能齐全的JavaScript风格的克隆,即使是内置的,你也不能这样做

<>也要记住,在java和C++等非原型语言中使用原型模式的主要动机是(a)避免<代码>新< /CODE >对象的成本,以及(b)允许向不同实例添加不同的方法或属性。对于前者,您并没有避免成本,而且在Python中这也不重要。对于后者,在Python中向实例添加方法和属性已经很容易了,而克隆并没有以任何方式让它变得更容易


我知道,与其他内置类型相比,数字类型有一些不同之处

不,这里的区别不是数字与序列,而是不变类型与可变类型:

>>> id(tuple())
4298170448
>>> id(tuple())
4298170448
>>> id(tuple(()))
4298170448
>>> id(tuple([]))
4298170448
此外,它与
int
tuple
构造函数的花式无关。如果该值未缓存在任何位置,则即使是重复的文字每次都会获得一个新实例:

>>> id(20000)
4439747152
>>> id(20000)
4439747216
小整数、空元组和不可关联的魔法常量的值在启动时被预先缓存。短字符串通常会被拘留。但具体细节取决于实现


那么,这对你有什么影响

嗯,克隆不可变类型是毫无意义的。根据定义,它是同一事物的不可更改的复制品,那么这又有什么好处呢


同时,不使用
\uuuu dict\uuuu
存储的类型不能以这种方式克隆(无论它们是内置类型、使用插槽的类型、动态生成属性的类型等等)。在某些情况下,你会得到一个错误,在其他情况下,只是错误的行为

因此,如果通过“序列、映射和数字类型”包括内置的
int
list
、stdlib类型(如
Decimal
deque
)或常见的第三方类型(如
gmpy.mpz
blist.sortedct
),则此机制将不起作用


除此之外,即使可以克隆内置类,也不能向它们添加新属性:

>>> a = []
>>> a.foo = 3
AttributeError: 'list' object has no attribute 'foo'
所以,如果你让它工作,它也不会有任何用处


同时,调用
object.\uuuuu new\uuu
而不是
type(instance)。\uuuu new\uuuu
会导致