Dan*_*ier 8 oop design-patterns python-3.x
我正在尝试实现一个接口,并且该接口由两个具体类采用,并且class First
,class Second
我有另一个类将这两个类作为父类class CO
。根据class CO
标志来决定返回两个继承类中的哪一个,以便使用它们的实现。
from abc import ABC, abstractmethod
class common(ABC):
@abstractmethod
def firstfunction(self):
pass
@abstractmethod
def secondfunction(self):
pass
class First(common):
def __init__(self)-> boto3:
self.ert = "danish"
# self.username = kwargs["username"]
# self.password = kwargs["password"]
print("Inside First function")
def firstfunction(self):
print("My implementation of the first function in FIRST CLASS")
def secondfunction(self):
print("My implementation of the second function in FIRST CLASS")
class Second(common):
def __init__(self):
self.rty = "pop"
# self.session_id = kwargs["session_id"]
print("Inside Second function")
def firstfunction(self):
print("My implementation of the first function in SECOND CLASS")
def secondfunction(self):
print("My implementation of the second function in SECOND CLASS")
class CO(First, Second):
def __init__(self):
self.inst = self.jo()
def jo(self):
a = True
if a:
main_object = First()
return main_object
else:
main_object = Second()
Run Code Online (Sandbox Code Playgroud)
我正在实例化并调用方法
mymainclass = co()
objt = mymainclass
objt.firstfunction()
objt.secondfunction()
Run Code Online (Sandbox Code Playgroud)
所以我的条件是,如果在类flag a = True
中CO
,则应该使用方法的具体类First
实现,我们应该得到如下输出:
第一个函数内部
我在 FIRST CLASS 中实现的第一个函数
我在 FIRST CLASS 中实现第二个函数
如果flag a = False
在类中CO
,那么应该使用具体类Second
,我们应该得到如下输出:
在第二个函数内部
我在 FIRST CLASS 中实现的第一个函数
我在 FIRST CLASS 中实现第二个函数
从给定的代码中,我得到了该标志的以下输出a = False
:
在第二个函数内部
我在 FIRST CLASS 中实现的第一个函数
我在 FIRST CLASS 中实现第二个函数
有人能让这段代码工作吗?我究竟做错了什么?我知道我可以创建一个函数,将这两个类作为变量,然后根据条件返回我想要的内容。但我想使用类来实现同样的目的
我不会CO
从First
或继承 class Second
,因为您希望最终得到一个作为classFirst
或class实例的对象Second
。最直接的方法是定义方法,__new__
这将使您能够更好地控制实例创建。
保持所有代码相同(修复明显的错误,例如boto3
未定义之后)并更改类,CO
如下所示:
class CO:
def __new__(cls):
a = True
if a:
main_object = First()
else:
main_object = Second()
return main_object
o = CO()
print(type(o))
Run Code Online (Sandbox Code Playgroud)
印刷:
Inside First function
<class '__main__.First'>
Run Code Online (Sandbox Code Playgroud)
如果您想更好地参数化实例创建(并简化 中的代码__new__
),则将变量a
作为参数CO
:
class CO:
def __new__(cls, a):
return First() if a else Second()
o = CO(False)
print(type(o))
Run Code Online (Sandbox Code Playgroud)
印刷:
Inside Second function
<class '__main__.Second'>
Run Code Online (Sandbox Code Playgroud)
您可以选择将类CO
作为common
其基类,以记录实例化此类会产生实现该common
接口的实例。但这样做不会导致强制执行返回的实际类型__new__
:
class CO(common):
def __new__(cls, a) -> common:
# The Python interpreter is not type-checking what is returned:
#return First() if a else Second()
return []
o = CO(False)
print(type(o))
Run Code Online (Sandbox Code Playgroud)
印刷:
<class 'list'>
Run Code Online (Sandbox Code Playgroud)
您还可以用工厂函数替换 class CO
:
def common_factory(a):
return First() if a else Second()
o = common_factory(False)
Run Code Online (Sandbox Code Playgroud)
笔记
如果您想确保从基类继承的类common
必须重写两者firstfunction
,并secondfunction
更紧密地模拟其他面向对象语言中实现的纯接口,那么您应该定义这些函数,以便common
它们引发NotImplementedError
异常:
class common(ABC):
@abstractmethod
def firstfunction(self):
raise NotImplementedError
@abstractmethod
def secondfunction(self):
raise NotImplementedError
Run Code Online (Sandbox Code Playgroud)
不幸的是,强制执行是在运行时完成的,这会带来意想不到的后果,而不是像其他面向对象语言那样在编译时完成。