Python和新实例

Python和新实例,python,Python,虽然我熟悉其他编程语言,但我仍在努力理解python中的代码,以及为什么在重新分配类时没有重置类属性。。。我在notify类中有一个方法 def send(self): for service in self.hosts: # func = getattr(self, service) for host in self.hosts[service]: try: if service == 'xbmc':

虽然我熟悉其他编程语言,但我仍在努力理解python中的代码,以及为什么在重新分配类时没有重置类属性。。。我在notify类中有一个方法

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
很明显,我没有得到不想要的效果,但是知道为什么我最初的方法不起作用或者如何克服它也很好。我们需要重置方法吗?或者实际上有没有一种方法可以在类之外创建一个新实例?还是我的代码有问题?谢谢……

有问题吗 这个问题是由于类属性
hosts
是可变的(列表),因此附加到它会影响每个实例

解决方案 解决方案是将类属性更改为实例属性:

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...
Xbmc类:
# 
应该是

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

第一个版本创建一个在所有Xbmc实例之间共享的列表。第二个为每一个创建一个列表。

但我认为,因为它在类范围内,并且是类的属性,所以这应该是无关的?@Edhen:我不这么认为。是的,它是一个类的属性。它位于一个类中(尽管可以从实例和外部访问)。不,这不是无关紧要的-可变是可变的,如果你改变它,它有新的价值。我只是把主机放在那里,因为它太容易阅读,看不到我的类有什么属性。。。谢谢你的回答,但它仍然让我明白为什么主机的行为不像一个公共财产,而它在那个类中是完全正确的。。。它是一个类的属性。。。。如果我做了php$x=newxbmc($hosts)。。不管这些属性中的内容是什么,每次我创建一个新实例时,这些属性都会被重置,除非它们是静态的……经过一些测试,结果证明你关于它是可变的是正确的,这让我完全不明白为什么(我需要仔细阅读),但你的答案是正确的。正如我所提到的,这个问题是因为
主机
实际上是一个可变的-如果它是
,则不会导致每个实例被覆盖。所以从技术上讲,外部的是静态属性?@Edhen,从技术上讲,它们是类属性。但对于大多数意图和目的,这与其他语言中的静态属性是一样的。
class Xbmc:
  hosts = []
  def __init__(self, host = None):
    self.setHosts(host)
    self.server = Hosts().getHostsByService('xbmcserver')
class Xbmc:
  def __init__(self, host = None):
    self.hosts = []
    self.setHosts(host)
    self.server = Hosts().getHostsByService('xbmcserver')