Python 动态选择要从中继承的类

Python 动态选择要从中继承的类,python,class,inheritance,Python,Class,Inheritance,我的Python知识有限,在以下情况下需要一些帮助 假设我有两个类A和B,是否可以在Python中执行类似于以下概念的操作: import os if os.name == 'nt': class newClass(A): # class body else: class newClass(B): # class body 所以问题是,我想创建一个类newClass,这样它就可以根据平台差异从不同的基类继承,这在Python中可以做到吗? 谢谢。您可以

我的Python知识有限,在以下情况下需要一些帮助

假设我有两个类A和B,是否可以在Python中执行类似于以下概念的操作:

import os
if os.name == 'nt':
    class newClass(A):
       # class body
else:
   class newClass(B):
       # class body
所以问题是,我想创建一个类newClass,这样它就可以根据平台差异从不同的基类继承,这在Python中可以做到吗? 谢谢。

您可以使用:


是的,你可以完全按照你写的做。虽然就我个人而言,为了保持清洁,我可能会这样做:

class _newClassNT(A):
    # class body

class _newClassOther(B):
    # class body

newClass = _newClassNT if os.name == 'nt' else _newClassOther
这假设您需要在类主体内实际执行不同的操作。如果只需要更改继承,则可以在此处嵌入If语句:

class newClass(A if os.name == 'nt' else B):
    # class body

来自Java和C的世界,想到要做这样的事情,我会畏缩不前。并不是说有条件地继承类的想法不好——我只是不习惯

想一想,如果这个问题是关于Java的,我会这样做。我正在发布模式-实现一个接口,然后使用工厂在实现之间进行选择-以便为问题提供另一个视角:

public interface OsDependent {
  public void doOsDependentStuff();
}

public class WindowsDependentComponent implements OsDependent {
  @Override
  public void doOsDependentStuff() {
    //snip
  }
}

public class AppleDependentComponent implements OsDependent {
  @Override
  public void doOsDependentStuff() {
    //snip
  }
}

public class OsDependentComponentFactory {
  public OsDependent getOsDependentComponent(Platform platform) {
    if(platform == Platform.WINDOWS)
      return new WindowsDependentComponent();
    else if(platform == Platform.APPLE)
      return new AppleDependentComponent();
    else
      return null;
  }
}
当然要编写更多的代码,但在强类型环境中这是一个合适的解决方案

编辑:我注意到我的答案和原来的问题有一个显著的区别:

如果有条件地从多个不同的类继承,则超类包含的代码取决于您使用的操作系统,而从超类继承的类包含的代码与所有操作系统的代码相同。继承链的顶端依赖于操作系统;底部不是


我的方法正好相反。OSDependent接口或超类定义了适用于所有平台的类似方法,而不同的实现或子类具有依赖于操作系统的代码。继承链的顶端是操作系统无关的。

当您有两个以上的选项可供选择时,我找到了自己的动态继承类的方法。我相信其他人在我之前也使用过这个,但是我在网上找不到类似的东西,所以我想我应该和你们分享

class A():
    # Class A Body
class B():
    # Class B Body
class C():
    # Class C Body
class D():
    # Class D Body
def MakeObject(InheritedClassName): # InheritedClassName is a string
    def CheckClass(InheritedClass):
        if InheritedClass == "A":
            return A
        elif InheritedClass == "B":
            return B
        elif InheritedClass == "C":
            return C
        else:
            return D
    class WantedClass(CheckClass(InheritedClassName)):
        # WantedClass Body
    YourObject = WantedClass()
    return YourObject
CreateObject = MakeObject(str(input("Chose A, B, C or D")))

这段代码可以修改,你可以用它做相当多的分配。这是我最喜欢的设置动态类继承的方法,尽管它有点长,因为您可以有任意多个选项,甚至可以为每个对象动态选择多个继承。

适用于那些在使用不同模块时有类似需求的人。 首先,创建一个fileswitcher.py并将以下内容放入其中

class Switcher():
    def choose(clname):
         Switcher.clname = clname
接下来,在newClass.py put中

最后在你的主脚本中

import switcher
import os
    if os.name == 'nt':
        switcher.Switcher.choose(A):
    else:
        switcher.Switcher.choose(B):

# that's the moment you're creating class with desired inheritance
import newClass.newClass

非常感谢您的回复@taocp没问题,很高兴我能帮上忙。这是一个更优雅的解决方案,因为它不需要重复类主体,但原始帖子中建议的逻辑也会起作用。尽管如果你能切实做到,如果您在另一个模块中有条件地使用单个变量名创建了a或B,然后将分配给a或B的名称导入到其他任何地方,这很有可能是更好的抽象。非常感谢您的帮助!为什么要这样做,而不是根据条件将A或B分配给BaseCls,然后再将newClassBaseCls类分配给BaseCls?我肯定更喜欢将其转换为python或Henry Keiter的解决方案。虽然arshajii的一个很好而且简单,但它只能处理两种不同的操作系统类型,因此它不是未来安全的,正如Robert C.Martin在他的精彩著作《干净的代码》中指出的那样,安全比抱歉更好。Python运行在太多不同的平台上,无法忽略这一事实…
import switcher

class newClass(switcher.Switcher.clname):
    ...
import switcher
import os
    if os.name == 'nt':
        switcher.Switcher.choose(A):
    else:
        switcher.Switcher.choose(B):

# that's the moment you're creating class with desired inheritance
import newClass.newClass