python - 子类化、继承和子类选择
问题描述
我想构建一个类和子类,其中子类从超类继承一些方法。
到目前为止没有什么特别的,但我希望能够根据参数创建子类,例如这应该与示例代码中的a = Shape(sides=3, base=2, height=12)
结果相同:c = Triangle(base=2, height=2)
class Shape:
def __new__(cls, sides, *args, **kwargs):
if sides == 3:
print('a')
return Triangle(*args, **kwargs)
else:
return Square(*args, **kwargs)
def __init__(self, a):
self._a = a
@property
def a(self):
return self._a
class Triangle(Shape):
def __init__(self, base, height):
super().__init__(self, a='triangle')
self.base = base
self.height = height
def area(self):
return (self.base * self.height) / 2
class Square(Shape):
def __init__(self, length):
Shape.__init__(self, a='square')
self.length = length
def area(self):
return self.length * self.length
a = Shape(sides=3, base=2, height=12)
b = Shape(sides=4, length=2)
c = Triangle(base=2, height=2)
print(c.a)
print(str(a.__class__))
print(a.area())
print(str(b.__class__))
print(b.area())
这会引发错误TypeError: __new__() missing 1 required positional argument: 'sides'
。
当我不继承类(做class Triangle:
)时,它不会抛出错误,但我当然不能再使用该函数a
了......
有什么提示吗?到目前为止,我的解决方案基于https://stackoverflow.com/a/60769071、https://stackoverflow.com/a/61509283和https://www.code-learner.com/how-to-use-python -新方法示例/
一种可能性是使用工厂模式,但我真的很喜欢覆盖新功能的想法......
解决方案
您正在继承&类Shape
中的类,这将导致对类的无限递归调用。Triangle
Square
__new__
Shape
使用 Factory 类对您的代码进行了一些修改以实现它。
class Shape:
def __init__(self, a):
self._a = a
@property
def a(self):
return self._a
class ShapeFactory:
def __new__(cls, sides, *args, **kwargs):
if sides == 3:
print('a')
return Triangle(*args, **kwargs)
else:
return Square(*args, **kwargs)
class Triangle(Shape):
def __init__(self, base, height):
super().__init__(a='triangle')
self.base = base
self.height = height
def area(self):
return (self.base * self.height) / 2
class Square(Shape):
def __init__(self, length):
Shape.__init__(self, a='square')
self.length = length
def area(self):
return self.length * self.length
a = ShapeFactory(sides=3, base=2, height=12)
b = ShapeFactory(sides=4, length=2)
c = Triangle(base=2, height=2)
print(c.a)
print(str(a.__class__))
print(a.area())
print(str(b.__class__))
print(b.area())
推荐阅读
- javascript - 如何使用 react js 和 Laravel 将表单数据发布到 web api
- reactjs - React Material UI GridList行/列问题
- c# - 在将项目保存到数据库之前强制文本框数据绑定更新
- android - 如何从每页项目数和总项目数 API 响应中获取总页数?
- c++ - 带有模板模板参数的 CRTP 派生类
- javascript - 有没有办法在 cron 中立即启动作业,然后在执行完成后停止它?
- python - 在创建并使用 django 提交其表单后将作者重定向到他的帖子
- jquery - 在检查 if 后使用 javascript 将某些类设置为 html
- python - 如果 docx 文件打开,则关闭它
- php - cURL - how can I turn into a variable