可以通过引用与其依赖的类同名的子类的方式来调用父类的方法吗?

问题描述 投票:0回答:1

我有一个

Game
引用类
HouseRules
Card
Player
。我想为每个类添加功能。

我创建了一个名为

Game
的子类以及名为
HouseRules
Card
Player
的子类,除了相应父类的方法和属性之外,它们还具有新的方法和属性。我希望未更改的方法仍能按预期运行,只是它们引用每个类的更新形式。下面是我的最小可重现示例,其中只有一个类(子类)依赖于一个类(子类)。

我创建了一个类

Foo
,它接受类
Obj
的对象进行初始化。如果未给出对象,则将其设置为默认值
Obj()

'src.py'
class Obj:
    def __init__(self, a=1, b=1): 
        self.a = a 
        self.b = b

class Foo:
    def __init__(self, obj=None):
        self.obj=Obj() if obj is None else obj
        ...

我想在新项目中构建

Foo
的功能,因此我创建了一个新文件并子类化
src.Foo

这个新的

Foo
的功能需要稍微复杂一点的
Obj
,它有一个属性
z
,所以我做了一个
src.Obj
的子类。

'main.py'
import src
class Obj(src.Obj):
    def __init__(self, z=0, **kwargs):
        self.z = z
        super().__init__(**kwargs)

class Foo(src.Foo):
    def __init__(self, obj=None):
        #self.obj=Obj() if obj is None else obj
        super().__init__(obj)

最初我没有包含注释行。我认为如果

obj
被传递为
None
super().__init__(obj)
会将
obj
变成新的改进的
Obj()
。 但它变成了旧的
Obj()
并在我尝试访问其不存在的属性
z
时抛出错误。

所以,我添加了该行并修复了它。


另一个想法是替换

'src.py'
class Foo:
    def __init__(self, obj=None):
        self.obj=Obj() if obj is None else obj

'src.py'
class Foo:
    def __init__(self, obj=None):
        self.obj=self.default_obj if obj is None else obj

    @property
    def default_obj(self): return Obj()

然后复制 getter 并将其粘贴到 'main.py' 中的

Foo
中,它将从 'main.py' 返回
Obj()


第三个想法是使

Obj
成为一个嵌套类并将
self.obj
设置为
self.Obj()

'src.py'
class Foo:
    class Obj:
        def __init__(self, a=1, b=1): 
            ...

    def __init__(self, obj=None):
        self.obj=self.Obj() if obj is None else obj
        ...
'main.py'
import src
class Foo(src.Foo):
    class Obj(src.Foo.Obj):
        def __init__(self, z=0, **kwargs):
            ...

    def __init__(self, obj=None):
        super().__init__(obj)

我听说嵌套类通常是应该避免的。另外,我注意到我无法使用

super().Obj
,我必须输入
src.Foo.Obj
,这意味着如果我更改超类的名称或其他内容,我必须确保在两个地方更改它。

但我的问题是:为了避免重复

obj
分配行(或者重复 getter 或类继承,或者让 src.py import main),是否有任何方法可以调用父类的初始化会将
obj
变成 'main.py' 中的
Obj()
而不是 'src.py' 吗? 虽然在这种最小的情况下它只是重复一个简单的行(或 getter),但我实际上有三个更新的子类。要使用我考虑过的这些技术,意味着将创建这些子类实例的所有超类方法逐字复制到子类中,以便它们引用新的子类,这会削弱使用继承的好处。 如果有比子类化项目的每个类更好的实践来实现我正在尝试的目标,请随时告诉我。

python file subclass instantiation superclass
1个回答
0
投票

首先,不要使用嵌套类。 :-)

因此,一种简单的方法就是将您所依赖的与基相关的类作为基中的类属性

Foo
(或
Game
) - 并检索该属性来实例化每个类。然后,在
Foo
(
Game
) 的子类中,只需覆盖这些属性即可。

无需搞乱属性或其他什么:

# src.py

class Obj:
    ...

class Foo:
    # This binds this class.Obj to the "Obj" visible in
    # the global scope
    Obj = Obj
    def __init__(self, obj=None):
        self.obj=self.Obj() if obj is None else obj
        
...
# other.py
import src
class Obj(src.Obj):
    # add extra stuff and overrides as desired!
    ...

class Foo(src.Foo):
    # Binds the class Obj attribute to the Obj visible here!
    Obj = Obj
    
    # Just with that, if nothing changes in __init__
    # you don't even need to redeclare it and call super()...:
    # the original Foo.__init__ will take care of
    # instantianting the derived Obj visible here!
    
© www.soinside.com 2019 - 2024. All rights reserved.