Ответ 1
Вы можете использовать условное выражение :
class newClass(A if os.name == 'nt' else B):
...
Знания My Python ограничены, мне нужна помощь в следующей ситуации.
Предположим, что у меня есть два класса A
и B
, можно ли сделать что-то вроде следующего (концептуально) в Python:
import os
if os.name == 'nt':
class newClass(A):
# class body
else:
class newClass(B):
# class body
Итак, проблема в том, что я хотел бы создать класс newClass
, чтобы он наследовал от разных базовых классов на основе разницы в платформе, возможно ли это сделать в Python?
Спасибо.
Вы можете использовать условное выражение :
class newClass(A if os.name == 'nt' else B):
...
Да, вы можете делать именно то, что вы написали. Хотя лично я, вероятно, сделал бы это так для чистоты:
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 и С#, мысль о том, чтобы делать что-то подобное, делает меня cringe = P. (Не то, что идея условного наследования класса плоха - я просто не привык к этому.)
Размышляя об этом немного, я бы сделал что-то подобное, если бы этот вопрос касался Java. Я отправляю шаблон - реализую интерфейс, затем использую factory для выбора между реализациями - чтобы обеспечить еще одну перспективу проблемы:
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;
}
}
Определенно намного больше кода, но это подходящее решение в строго типизированной среде.
EDIT: Одна существенная разница, которую я заметил между моим ответом и оригинальным вопросом:
Если вы условно наследуете от нескольких разных классов, то суперклассы содержат код, который зависит от используемой ОС, в то время как класс, который наследует от них, содержит код, который является одинаковым для всех ОС. Верхняя цепочка наследования зависит от ОС; внизу нет.
Мой подход идет другим путем. Интерфейс OsDepndent
(или суперкласс) определяет методы, похожие для всех платформ, в то время как разные реализации (или подклассы) имеют код, зависящий от ОС. Верхняя цепочка наследования является OS-агностиком.
Я нашел свой собственный способ динамического наследования классов, когда у вас есть более двух вариантов выбора. Я уверен, что другие использовали это передо мной, но я не мог найти ничего подобного в Интернете, поэтому я подумал, что должен поделиться им с вами.
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")))
Этот код может быть изменен, и вы можете сделать с ним достаточно. Это мой любимый способ настройки динамического наследования классов, хотя он немного длинный, так как у вас может быть столько вариантов, сколько вы хотите, и даже может иметь несколько динамически выбранных наследований для каждого объекта.
Для тех, кто имеет схожие потребности, работая с разными модулями.
Сначала создайте файл switcher.py
и вставьте в него
class Switcher():
def choose(clname):
Switcher.clname = clname
Далее, в newClass.py
поставьте
import switcher
class newClass(switcher.Switcher.clname):
...
Наконец, в вашем главном script
import switcher
import os
if os.name == 'nt':
switcher.Switcher.choose(A):
else:
switcher.Switcher.choose(B):
# that the moment you're creating class with desired inheritance
import newClass.newClass