Python中的有用继承。接口的替代方案

时间:2009-11-10 07:25:56

标签: python inheritance interface

嗨,据我所知,Python变量是无类型的。所以现在我想要一个基类

class baseClass:
 def x():
  print "yay"

和两个子类

class sub1(baseClass):
 def x(): 
  print "sub1"

class sub2(baseClass):
 def x():
  print "sub2"

在其他编程语言中我可以像

那样针对接口进行开发
baseClass c = new sub1()

所以现在我可以使用c作为具有sub1功能的baseClass,也许在运行时我可以通过

更改它
c = new sub2()

在python中也可以吗?

3 个答案:

答案 0 :(得分:5)

c = sub1()
c = sub2()

但是基类和定义接口的概念是不必要的,因为python不是静态类型的。

编辑:

用有效的Python重写代码:

# This space where baseClass was defined intentionally left blank, 
# because it serves no purpose

class Sub1(object):
  def x(self): 
    print "sub1"

class Sub2(object):
  def x(self):
    print "sub2"

c = Sub1()
c = Sub2()

答案 1 :(得分:2)

是的,你可以这样做;但是,实例化对象的语法不是“new Class(args)”。只需删除“新”。

退一步,假设您有一个对象存储在名为foo的变量中。编译器永远不会抱怨您执行以下操作:

foo.bar

即使foo无法拥有属性栏也是如此。这是因为foo是否具有名为bar的属性是在运行时确定的(这就是Python是dynamically typed语言的原因)。如果您的代码存在类型问题,则在实际运行它(即运行时)之前可能无法找到它。

在Python中,接口完全按照惯例在同一项目的开发人员之间建立。这种处理接口的方法称为duck typing。我建议你阅读这个主题,因为你似乎是Python的新手。

PS:动态类型可能听起来像是一件坏事,因为你没有得到编译时类型检查,但另一方面是你必须编写的锅炉板少得多。从理论上讲,这会让你更有效率。根据我的经验,这往往会结束。

答案 2 :(得分:1)

Python实际上没有“变量”。 Python的名称是绑定了对象的名称。

class X(object):
    pass
class Y(object):
    pass
class Z(object):
    pass

a = X  # name "a" bound with class object "X"

print(a is X)  # prints True

a = Y
print(a is Y)  # prints True
b = Y
print(a is b)  # prints True

上面的代码显示了名称“a”与第一个对象(类对象定义为“X”)和另一个对象(类对象“Y”)的绑定。然后我们将“b”绑定到类对象“Y”。然后“a”和“b”引用同一个对象,因此is测试返回True

Python是强类型的。只要“a”与类对象“Y”绑定,“a”的类型就是类对象的类型。例如,如果您尝试在数学表达式中使用“a”,Python将引发TypeError异常,因为“a”将是错误的类。

print(a + 3)  # causes TypeError exception

但重新绑定一个名称以指向可能具有其他类型的其他对象总是合法的。

a = 3
print(a + 3)  # prints 6

这里有一个很好的解释: http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html#python-has-names