让子类从实例化的主类继承非默认__init__值

时间:2018-08-16 16:09:02

标签: python python-2.7 inheritance

如何有一个子类,它不仅可以从主类继承__init__变量,还可以从实例化的主类继承实例化的值。

例如,说我有以下课程:

class MainClass(object):
    def __init__(self, mainVar1=None, mainVar2=None):
        self.mainVar1 = mainVar1
        self.mainVar2 = mainVar2

class SubClass(MainClass):
    def __init__(self):
        super(SubClass, self).__init__()
        self.subVar1 = -1

我这样做:

main = MainClass(mainVar1=1, mainVar2=2)
sub = SubClass()
print(sub.mainVar1)

这会打印出None而不是1,因为sub调用了__init__中的MainClass,其中mainVar1默认设置为{ {1}}。

我想做的是实例化None,以使其获取用于实例化SubClass的输入值,这样MainClass会打印print(sub.mainVar1) 1中的。

我想在实例化类时不重复相同的变量:

None

这可能吗?这是一个糟糕的设计选择吗?最好的方法是什么?

编辑:

具体示例

我有一个名为main = MainClass(mainVar1=1, mainVar2=2) # This is what I'm trying to avoid. sub = SubClass(mainVar1=1, mainVar2=2) print(sub.mainVar1) 的类,该类提供用于访问服务器上数据的功能。这是上面示例中的ServerTools类。要实例化此类,我需要一个MainClassusernamepassword

然后我有一个名为server_url的子类,该子类根据服务器上的数据创建文档。要实例化此类,我需要Docsusernamepassword和其他一些参数。该子类需要主类server_url中的函数来访问服务器上的数据。

我的思维过程是使ServerTools成为Docs中的工具,在该工具中,如果不实例化ServerTools则无法创建文档。我不确定ServerTools应该是子类,内部类还是完全其他的东西。

2 个答案:

答案 0 :(得分:1)

您可以使用splat和splatty splat运算符传递参数:

sub

通过继承记住MainClassisinstance(sub, MainClass)的实例:True将返回MainClass。您根本不需要meth1的单独实例。

作为扩展示例,即使您在MainClass中有一个名为SubClass的方法并在MainClass.meth1(sub, ...) 中覆盖了该方法,您仍然可以像这样调用它:

onEdit

答案 1 :(得分:1)

对于您的实际设计,听起来好像根本不需要子类。

根据要建模的实际对象以及它们之间的关系来考虑对象模型,通常可以更清楚地知道应如何编写类。

您有一个ServerTools班。此类的实例表示服务器或与服务器的连接或类似的东西。

您有一个Docs班。此类的实例表示服务器上的文档。

每个Docs对象都不是服务器,因此不应 一个ServerTools实例。但是每个Docs对象都有一个存储在其上的服务器,因此它应该拥有一个ServerTools对象。


因此,您可能要像这样建模:

class ServerTools(object):
    def __init__(self, username, password, server_url):
        self.username = username
        self.password = password
        self.server_url = server_url

class Docs(object):
    def __init__(self, server, path):
        self.server = server
        self.path = path

myserver = ServerTools('me', 'swordfish', 'smb://chico.example.com')
mydocs = Docs(myserver, '/Horse/Feathers')

或者,如果您很少单独需要ServerTools对象,并且想为每个Docs对象创建一个对象,则可以在初始化程序中创建它。为此,您将所有相关的ServerTools-construction参数作为参数:

class Docs(object):
    def __init__(self, username, password, url, path):
        self.server = ServerTools(username, password, url)
        self.path = path

mydocs = Docs('me', 'swordfish', 'smb://chico.example.com' '/Horse/Feathers')

作为旁注,我不确定您为什么要让这些参数具有默认值None。为什么要创建一个没有ServerTools的{​​{1}}?因此,我保留了默认设置。但是如果您有理由使用它们,可以重新添加它们。