1

虽然我熟悉其他编程语言,但我很难理解我在 python 中的代码以及为什么当我重新分配类时我的类属性没有被重置......例如。我在通知类中有一个方法

def send(self):
    for service in self.hosts:
      # func = getattr(self, service)
      for host in self.hosts[service]:
        try:
          if service == 'xbmc':
            self.xbmc(host)
          elif service == 'growl':
            self.growl(host)
          elif service == 'prowl':
            self.prowl(host)
        except:
          print "Cound't connect " + host.find('ip').text + " For " + service

如您所见,这将遍历每个服务(所以请记住,我有 3 个 xbmc)

所以以xbmc为例,方法是

def xbmc(self, host):
  x = Xbmc(host)
  x.notify(self.title, self.message)

在其他语言下,如果我再次分配 x,这将是一个全新的对象,但 python 似乎不是这种情况......

我将从我的 xbmc 课程中放置片段来解释这个问题。

class Xbmc:
  hosts = []
  def __init__(self, host = None):
    self.setHosts(host)
    self.server = Hosts().getHostsByService('xbmcserver')

  def setHosts(self, host = None):
     ...alot of elif...
     elif type(host).__name__ == 'Element': # this code is the one that is in effect from my notify class
       self.hosts.append(host)
     ...more elif...
     print self.hosts # for debugging

现在代码就在那里,当我启动通知发送时。输出显示:

[<Element 'host' at 0x7fdda19d0d10>]
XBMC 192.168.1.10 Failed To Connect
[<Element 'host' at 0x7fdda19d0d10>, <Element 'host' at 0x7fdda1955090>]
XBMC 192.168.1.10 Failed To Connect
XBMC 192.168.1.20 Failed To Connect
[<Element 'host' at 0x7fdda19d0d10>, <Element 'host' at 0x7fdda1955090>, <Element 'host' at 0x7fdda19553d0>]
XBMC 192.168.1.10 Failed To Connect
XBMC 192.168.1.20 Failed To Connect
XBMC 192.168.1.21 Failed To Connect

很明显,当我附加主机时,它实际上从来没有一个新实例,但总是附加到已经存在的东西......我假设 x = Class() 会启动一个新实例?如果我做

self.hosts = [host]

那么显然我没有得到不希望的效果,但是知道为什么我的初始方法不起作用或如何克服它也会很好。我们需要重置方法吗?或者实际上有没有办法从一个类中创建一个新实例?还是我的代码有问题?谢谢....

4

2 回答 2

2

Problem

The problem is caused, because the class property hosts is mutable (list), so appending to it will influence every instance.

Solution

The solution is to change the class property into instance property:

class Xbmc:
    # <--- (no more "hosts" here)
    def __init__(self, host = None):
        self.hosts = []  # <--- we are initializing "hosts" property here now
        self.setHosts(host)
        self.server = Hosts().getHostsByService('xbmcserver')
    # and so on...
于 2012-10-10T00:15:24.103 回答
0
class Xbmc:
  hosts = []
  def __init__(self, host = None):
    self.setHosts(host)
    self.server = Hosts().getHostsByService('xbmcserver')

Should be

class Xbmc:
  def __init__(self, host = None):
    self.hosts = []
    self.setHosts(host)
    self.server = Hosts().getHostsByService('xbmcserver')

The first version creates a list shared between all Xbmc instances. The second creates a list for each one.

于 2012-10-10T00:17:11.513 回答