如何为此类的子类编写init?

时间:2019-05-28 10:11:29

标签: python class oop inheritance

我正在尝试从此类编写一个子类:

class InsertCreateAlter(object):

def __init__(self, url=None, engine=None, connection=None, session=None,
             **kwargs):
    if connection is not None:
        self.engine = connection
    elif engine is not None:
        self.engine = engine
    elif session is not None:
        self.engine = session
    else:
        self.engine = sqlalchemy.create_engine(url, **kwargs)

这是我到目前为止的尝试:

class InsertCreateAlterEAV(InsertCreateAlter):


def __init__(self, url=None, engine=None, connection=None, session=None,
             **kwargs):
    InsertCreateAlter.__init__(self, url=None, engine=None, connection=None, session=None,
             **kwargs)
    if connection is not None:
        self.engine = connection
    elif engine is not None:
        self.engine = engine
    elif session is not None:
        self.engine = session
    else:
        self.engine = sqlalchemy.create_engine(url, **kwargs)

当我将函数调用为:

InsertCreateAlterEAV(session=session)

我得到了错误:

Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/IPython/core/interactiveshell.py", line 3267, in run_code
    exec(code_obj, self.user_global_ns, self.user_ns)
  File "<ipython-input-4-ee54fec26f76>", line 2, in <module>
    InsertCreateAlterEAV(session=session)
  File "/Users/asportelli/Documents/gitRepos/etl/etl/eav/InsertCreateAlterEAV.py", line 18, in __init__
    **kwargs)
  File "/Users/asportelli/Documents/gitRepos/etl/etl/insert/InsertCreateAlter.py", line 27, in __init__
    self.engine = sqlalchemy.create_engine(url, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/__init__.py", line 425, in create_engine
    return strategy.create(*args, **kwargs)
  File "/usr/local/lib/python3.7/site-packages/sqlalchemy/engine/strategies.py", line 52, in create
    plugins = u._instantiate_plugins(kwargs)
AttributeError: 'NoneType' object has no attribute '_instantiate_plugins'

1 个答案:

答案 0 :(得分:3)

您不应复制父类的代码。这样做:

class InsertCreateAlterEAV(InsertCreateAlter):
    def __init__(self, url=None, engine=None, connection=None, session=None,
                 **kwargs):
        # Do you have code you want to run before running the parent's __init__?
        # Maybe adding default arguments or changing one of them?
        # Then add that code here.

        # init the parent
        super().__init__(url=url,
                         engine=engine,
                         connection=connection,
                         session=session,
                         **kwargs)

        # Here you can add code after the parent's init code. Maybe for
        # initializing subclass-specific attributes.

如果您仍在使用Python 2,请使用InsertCreateAlter.__init__(self, ...


现在让我们看看问题出在哪里。您可以按以下方式调用子类:

InsertCreateAlterEAV(session=session)

然后,您的子类将调用父类的__init__方法,但使用session=None。因此,父类采用此分支:

else:
        self.engine = sqlalchemy.create_engine(url, **kwargs)

,并且由于kwargs为空,因此仅url(即None)被传递到create_engine()This method does not know how to deal with url==None.

因此,您会得到一个例外。