无论如何,是否有其他方法可以覆盖其他模块中的类,同时将其方法保留在python

问题描述

为了说明我的问题,这里有3个模块:

这是模块A

'''
lets call this module the parent,it regroups multiple classes with several
method each
'''

class Rectangle():
    '''
    The basic rectangle class that is parent for other classes in this
    module
    '''
    def __init__(self,x_length,y_length):
        self.x_length = x_length
        self.y_length = y_length

    def create_points(self):
        '''
        Basic geometrical method 
        '''
        self.point_1 = [x_length/2,y_length/2]
        self.point_2 = [-x_length/2,y_length/2]
        self.point_3 = [-x_length/2,-y_length/2]
        self.point_4 = [x_length/2,-y_length/2]

class Square(Rectangle):
    '''
    The square that is a rectangle with two identical sides
    '''
    def __init__(self,side_dim):
        super().__init__(side_dim,side_dim)

class SquareCollection():
    '''
    Creates a composition relation with an other class of the module
    '''
    def __init__(self,dim_list):
        '''
        The constructor creates a square for every float in the given list
        '''
        for val in dim_list:
            try:
                self.element.append(Square(val))
            except AttributeError:
                self.element = [Square(val)]

    def create_points(self):
        for elmt in self.element:
            elmt.create_points()

这是模块B1

'''
lets call this module the child 1,it redefines the classes from the parent but
with an additionnal method specific for its use case
'''
import Module_A as ma

class Rectangle(ma.Rectangle):
    '''
    The basic rectangle class that is parent for other classes in this
    module
    '''
    def module_specific_method(self):
        self.special_attribute_1 = True

class Square(ma.Square):
    '''
    The square that is a rectangle with two identical sides
    '''
    def module_specific_method(self):
        self.special_attribute_1 = True

class SquareCollection(ma.SquareCollection):
    '''
    Redefining the SquareCollection with an additionnal method
    '''
    def module_specific_method(self):
        for elmt in self.element:
            elmt.module_specific_method()

这是模块B2

'''
lets call this module the child 2,it redefines the classes from the parent but
with an additionnal method specific for its use case
This module is a copy of Module_B2 and is used to justify the used code
structure
'''
import Module_A as ma

class Rectangle(ma.Rectangle):
    '''
    The basic rectangle class that is parent for other classes in this
    module
    '''
    def module_specific_method(self):
        self.special_attribute_2 = True

class Square(ma.Square):
    '''
    The square that is a rectangle with two identical sides
    '''
    def module_specific_method(self):
        self.special_attribute_2 = True

class SquareCollection(ma.SquareCollection):
    '''
    Redefining the SquareCollection with an additionnal method
    '''
    def module_specific_method(self):
        for elmt in self.element:
            elmt.module_specific_method()

当我导入模块B2时,创建一个sc = SquareCollection([4,3.5,0.8])实例,然后运行sc.module_specific_method(),对于使用A模块创建的被调用AttributeError类,我得到一个Square SquareCollection类继承自A模块中定义的类,而A模块本身根据同一模块中定义的类创建多个Square实例。之所以期望AttributeError是因为我在A模块中没有定义此module_specific_method

由于代码的结构以及当前的使用方式,我在使用模块B1或模块B2。我目前通过重写两次模块A中包含的所有内容一个在B1中,另一个在B2中)来避免此问题。因为我正在重构所有代码,所以我希望可以删除所有重复的代码,并将其放入“通用”模块中,如上面的简化示例所示。

模块A中的类如何继承/指向我调用它的B模块?

我希望我的问题很清楚,因为我真的很难将其形式化。

干杯!

解决方法

您可以通过将基Square中使用的SquareCollection类作为集合类的属性来实现此目的,这样,也不必硬编码,它也可以被子类显式覆盖:

# Module_A
class Square:
    pass      # implement stuff here

class SquareCollection
    BaseItem = Square    # the "class that is collected here"

    def __init__(self,dim_list):
        # spawn BaseItem instances here,which are Square by default,# but might be set to something else in a subclass
        self.element = [self.BaseItem(val) for val in dim_list]
# Module_B1
import Module_A as ma

class Square(ma.Square):
     pass

class SquareCollection(ma.SquareCollection):
    # override the collection's BaseItem with this module's Square class,# but keep the rest of the SquareCollection code the same
    BaseItem = Square    

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...