作为一个例子,只有几个虚拟对象将一起使用。 FWIW这是使用Python 2.7.2。
class Student(object):
def __init__(self, tool):
self.tool = tool
def draw(self):
if self.tool.broken != True:
print "I used my tool. Sweet."
else:
print "My tool is broken. Wah."
class Tool(object):
def __init__(self, name):
self.name = name
self.broken = False
def break(self):
print "The %s busted." % self.name
self.broken = True
Hammer = Tool(hammer)
Billy = Student(Hammer)
Tommy = Student(Hammer)
这可能是足够的代码,你知道我要去哪里。如果我调用Hammer.break(),我在对象的同一个实例上调用它;如果比利的锤子被打破了,那么汤米也是如此(毕竟它与锤子完全相同)。
现在很明显,如果该程序仅限于Billy和Tommy作为学生的实例,那么修复将是显而易见的 - 实例化更多的Hammers。但显然我在问,因为不是那么简单,呵呵。我想知道是否有可能创建对象,这些对象在每次被调用时都会显示为自己的唯一实例。
编辑:我得到的答案让我相信我对实例化的理解有一个漏洞。如果我有这样的事情:class Foo(object):
pass
class Moo(Foo):
pass
class Guy(object):
def __init__(self, thing):
self.thing = thing
Bill = Guy(Moo())
Steve = Guy(Moo())
每次我使用Moo()时,是一个单独的实例,还是它们都引用同一个对象?如果他们分开,那么我的整个问题都可以撤回,因为它会让我的思绪变得松散。
答案 0 :(得分:3)
您必须为每个学生创建工具的新实例。
class Student(object):
def __init__(self, tool):
self.tool = tool
def draw(self):
if self.tool.broken != True:
print "I used my tool. Sweet."
else:
print "My tool is broken. Wah."
class Tool(object):
def __init__(self, name):
self.name = name
self.broken = False
def break(self):
print "The %s busted." % self.name
self.broken = True
# Instead of instance, make it a callable that returns a new one
def Hammer():
return Tool('hammer')
# Pass a new object, instead of the type
Billy = Student(Hammer())
Tommy = Student(Hammer())
答案 1 :(得分:2)
我会尽量简短。嗯..我总是试着简短,但我的成功水平几乎是random.randint(0,从不)。所以是的。
洛尔。你甚至没有简短地宣布你会试着简短。
首先,我们需要明确“召唤成为”的含义。据推测,每次发生self.tool = object
时你都需要一把新锤子。您不希望每次都有新的实例,例如,您访问工具属性,或者每次检查self.tool.broken
时,您总是会得到一个新的,可能是完整的锤子。
一对夫妇。
一,给Tool一个复制方法,该方法产生一个新对象,该对象应该等于原始对象,但是是一个不同的实例。例如:
class Tool:
def __init__(self, kind):
self.kind = kind
self.broken = False
def copy(self):
result = Tool(self.kind)
result.broken = self.broken
return result
然后在学生的初学者中你说
self.tool = tool.copy()
选项二,使用工厂功能。
def makehammer():
return Tool(hammer)
class Student:
def __init__(self, factory):
self.tool = factory()
Billy = Student(makehammer)
我无法在Python中认为你可以编写行self.tool = object
并让对象自动复制,我认为你不想这样做。我喜欢Python的一件事是WYSIWYG。如果你想要魔法使用C ++。我认为,当你不仅无法分辨出一行代码在做什么时,你甚至不能告诉它正在做任何特殊的代码,这使得代码难以理解。
请注意,您可以使用工厂对象获得更好的体验。例如:
class RealisticFactory:
def __init__(self, kind, failurerate):
self.kind = kind
self.failurerate = failurerate
def make(self):
result = Tool(self.kind)
if random.random() < self.failurerate:
result.broken = True
if (self.failurerate < 0.01):
self.failurerate += 0.0001
return result
factory = RealisticFactory(hammer, 0.0007)
Billy = Student(factory.make)
Tommy = Student(factory.make) # Tommy's tool is slightly more likely to be broken
答案 2 :(得分:1)
您可以像这样更改行:
Billy = Student(Tool('hammer'))
Tommy = Student(Tool('hammer'))
这将为Student类的每个实例生成一个独特的Tool类实例。您发布的示例代码的问题在于您没有多次“调用工具”(使用您的单词)。
答案 3 :(得分:1)
每次要创建新工具时,只需调用工具('锤子')。
h1 = Tool('hammer')
h2 = Tool('hammer')
Billy = Student(h1)
Tommy = Student(h2)
答案 4 :(得分:0)
哦等等,我忘记了,Python确实有魔力。
class Student:
def __setattr__(self, attr, value):
if attr == 'tool':
self.__dict__[attr] = value.copy()
else:
self.__dict__[attr] = value
但我仍然说你应该谨慎使用魔法。
答案 5 :(得分:0)
在看到这里的答案并记住Python的禅之后,我将回答我自己的问题时说:“我可能应该更加努力地思考它。”
我将重申我自己的问题作为答案。假设我有这个小程序:
class Item(object):
def __init__(self):
self.broken = False
def smash(self):
print "This object broke."
self.broken = True
class Person(object):
def __init__(self, holding):
self.holding = holding
def using(self):
if self.holding.broken != True:
print "Pass."
else:
print "Fail."
Foo = Person(Item())
Bar = Person(Item())
Foo.holding.smash()
Foo.using()
Bar.using()
程序将为Foo.using()返回“Fail”,为Bar.using()返回“Pass”。在实际上在考虑我正在做什么时,“Foo.holding = Item()”和“Bar.holding = Item()”显然是不同的实例。我甚至运行这个愚蠢的程序来证明它是有效的,因为我推测它确实有效,并且对你们没有惊喜,它确实如此。所以我撤回了我的问题,因为当我提出时,实际上并没有使用我的大脑。有趣的是,通过我一直在研究的程序,我已经这样做了,但假设这是错误的方法。所以,谢谢你的幽默。