class Foo(object):
pass
t = (1,2,Foo()) # t is a tuple, :. t is immutable
b = a[2] # b is an instance of Foo
b.foo = "Hello" # b is mutable. (I just changed it)
print (hash(b)) # b is hashable -- although the default hash isn't very useful
d = {b : 3} # since b is hashable, it can be used as a key in a dictionary (or set).
c = t # even though t is immutable, we can create multiple references to it.
a = [t] # here we add another reference to t in a list.
现在,关于获取/存储全局引擎列表的问题--有几种不同的方法可以做到这一点,下面是一种:
class Engine(object):
def __init__(self, make, model):
self.make = make
self.model = model
class EngineFactory(object):
def __init__(self,**kwargs):
self._engines = kwargs
def all_engines(self):
return self._engines.values()
def __call__(self,make, model):
""" Return the same object every for each make,model combination requested """
if (make,model) in _engines:
return self._engines[(make,model)]
else:
a = self._engines[(make,model)] = Engine(make,model)
return a
engine_factory = EngineFactory()
engine1 = engine_factory('cool_engine',1.0)
engine2 = engine_factory('cool_engine',1.0)
engine1 is engine2 #True !!! They're the same engine. Changing engine1 changes engine2
用户类被认为是可变的。Python没有(绝对)私有属性,因此您可以通过访问内部来更改类。
要将类用作} method 和^{} method ,保证类是不可变的。在这种情况下,通常设计类API时不会在创建后对内部状态进行变异。
dict
中的键或将它们存储在set
中,可以定义^{例如,如果引擎是由其id唯一定义的,则可以将其用作哈希的基础:
现在可以在集合中使用类引擎的实例:
在上面的示例中,我向集合添加了另一个
Engine(1)
实例,但它被认为已经存在,并且集合没有更改。注意,就列表而言,
.__eq__()
实现是最重要的;列表并不关心对象是否可变,但是使用.__eq__()
方法,您可以测试给定引擎是否已经在列表中:所有对象(除了标准库中的一些对象,一些对象使用描述符和修饰符实现特殊访问机制,或者一些对象用C实现)都是可变的。这包括用户定义类的实例、类本身,甚至定义类的类型对象。您甚至可以在运行时更改类对象,并在修改之前创建的类实例中显示修改清单。总的来说,在Python中,只有当您深入挖掘时,事情才是不可变的。
我认为您将易变性与python保存引用的方式混淆了——考虑一下:
现在,关于获取/存储全局引擎列表的问题--有几种不同的方法可以做到这一点,下面是一种:
通过使用
EngineFactory._engines
dict storeweakref.ref
对象而不是实际存储对对象的实际引用,可以稍微改进上面的示例。在这种情况下,在返回对该对象的新引用之前,您需要检查以确保引用仍然有效(没有被垃圾回收)。相关问题 更多 >
编程相关推荐