2009-10-29 75 views
5

当我扩展了一些工具生成的类,直到我尝试使用super()时,我才意识到它们是旧式类。超()不能与旧样式类工作,所以我得到这个错误:扩展新旧风格类可以吗?

TypeError: super() argument 1 must be type, not classobj 

例如,试试这个片断:

>>> class A: 
...  def greet(self): 
...   print "A says hi" 
... 
>>> class B(A): 
...  def greet(self): 
...   print "B says hi" 
... 
>>> super(B, B()).greet() 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: super() argument 1 must be type, not classobj 

我只是好奇,如果我延长B将发生什么从对象,以及使它成为一个新的风格类,它似乎使超()的工作。

>>> class B(A, object): 
...  def greet(self): 
...   print "B says hi" 
... 
>>> super(B, B()).greet() 
A says hi 

这是一个合适的解决方法,否则我以后会有一些不必要的后果?

+2

为什么不能将'class A'改成'class A(object)'?什么阻止你修复根本原因并使所有的新风格都变成现实?为什么你认为解决方案比解决方案更好? – 2009-10-29 10:19:42

+1

原因是生成了类A(正如我在开始时提到的那样,我正在扩展工具生成的类)。如果我进行这种更改,下次重新生成类时,它们会被覆盖。 – haridsv 2009-10-29 18:41:54

回答

1

如果你不能改变发电机产生新的样式类,你可以后期处理的文件,使他们新的风格:

import re 
pat = re.compile("^(.*class\s+\w+)(:.*)$") 
out_file = open("edited_file.py", "w") 
for line in open("generated_file.py"): 
    m = pat.match(line) 
    if m: 
     line = m.group(1) + "(object)" + m.group(2) + "\n" 
    out_file.write(line) 

out_file.close() 

如果你不想这样做,因为某些原因,那么确定,继续并继承原始类和object。据我所知,这应该工作得很好;你的新班级将成为新式班级。

Python in a Nutshell(作者:Alex Martelli,O'Reilly出版)说如果你声明一个具有基类的类并且至少有一个基类是新类型的,它将永远是一个新类型的类。它没有列出与此行动有关的任何特别警告或危险。我认为你很好去。

4

新风格的类已经被推荐在Python中使用,因为它们是在Python 2.2中引入的。在Python 3.x中,只有新风格的类可用。因此,我建议您将课程转换为新式。

我不知道您可能会遇到任何实际问题。大多数情况下,新式课程只是带来了新功能,例如super()实际工作。如果你的代码依赖于旧式类的语义,那么这些代码当然会被破坏。 (想到的唯一例子是着名的Alex Martelli着名的Borg pattern)。

Here是一个链接到Python参考手册,讨论新风格类与旧式(“经典”)类。 here是一篇经典文章的链接,其中Guido van Rossum解释了为什么引入新式课程。

我只在代码中使用新式类,我鼓励你也这样做。

+0

感谢您的有趣链接。看看我的最新评论为什么A是旧式。 – haridsv 2009-10-29 18:55:08

+0

我很抱歉不理解你在问什么;当我写这篇文章的时候,我昨天一定累了。我写了第二个更好的答案。 – steveha 2009-10-29 22:00:51

0

除了一些方法依赖于经典语义或者你的经典基类使用元类(后代的元类将永远是一种新式类),我认为混合经典类和新风格类没有问题。

另一方面,我认为没有理由再使用经典类,所以更改class A:class A(object):是首选。

+0

然而,我同意你的看法,那就是生成A类。在上下文中,我所谈论的工具是ZSI包,它提供了wsdl2py和wsdl2dispatch工具。它们从2007年的某个时候起就没有被维护过,所以不知道它们什么时候会更新它用于python 3.0。现在,我仍然使用2.6,所以我没有这些生成的类的问题。我甚至没有看到用于实现SOAP服务器的可选新包。 – haridsv 2009-10-29 18:46:00