如何更改导入模块的导入?
我创建了一个程序包,我想在另一个项目中对其进行扩展。 导入的软件包如下所示:
/pck_name
/__init__.py
/point.py
/triangle.py
point.py:
class Point(object):
def __init__(self, name='test'):
self.name = name
triangle.py:
from pck_name.point import Point
class Triangle(object):
def __init__(self, points=None):
if points is None:
points = list()
for i in range(2):
points.append(Point())
self.points = points
然后我有另一个项目,其中我使用新方法定义了NewPoint类:
class NewPoint(object):
def __init__(self, name='test'):
self.name = name
def print_name(self):
print(self.name)
我要实现的是导入pck_name.triangle并使用NewPoint更改导入的Point以获取新功能:
from pck_name.triangle import Triangle
triangle = Triangle()
triangle.points[0].print_name()
我尝试了猴子补丁,但如果我对Point类进行补丁,则它是无用的,因为triangle.py中的import语句始终会导入原始Point类。
非常感谢您!
答案 0 :(得分:0)
您可以将工厂(类或函数)传递给Triangle
的“构造函数”:
class Triangle:
def __init__(self, points=None, factory=None):
if points is None:
if factory is None:
# instead of raising an error, you can use Point class by default
raise ValueError("Both points and factory not provided")
points = [factory() for _ in range(3)]
self.points = points
现在您可以通过以下方式使用它:
triangle = Triangle() # raises error
triangle = Triangle(points=...) # uses provided points
triangle = Triangle(factory=NewPoint) # creates a triangle with NewPoints
编辑:;此外,如果您想使用某种别名,则可以使用functools.partial
:
NewPointTriangle = functools.partial(Triangle, factory=NewPoint)
DefaultPointTriangle = functools.partial(Triangle, factory=Point)
现在:
triangle = NewPointTriangle() # creates NewPoints
triangle = DefaultPointTriangle() # creates Points
triangle = NewPointTriangle(points=...) # uses provided points
triangle = DefaultPointTriangle(points=...) # uses provided points
答案 1 :(得分:0)
如果我正确理解,您想修改Triangle类的行为,而无需实际“接触”代码。这不是最好或优雅的方法,但也许会以某种方式有用:
import sys
if sys.modules.get('NewPoint'):
# clear and update the Triangle.points list
triangle.__dict__['points'].clear()
for i in range(2):
triangle.__dict__['points'].append(NewPoint())
答案 2 :(得分:0)
目前,我已经通过覆盖导入的模块解决了该问题。缺点是我必须以正确的顺序导入和覆盖模块。这意味着我必须先导入并覆盖要覆盖的类或函数,然后再将其导入其他任何地方。这不是一个完美的解决方案,因为很难确定何时导入某些内容。 一位朋友告诉我,他通过助手功能解决了一个相关问题。您对此有任何经验吗?