【问题标题】:How do I use *args with class inheritance in python?如何在 python 中使用 *args 和类继承?
【发布时间】:2020-12-21 04:16:43
【问题描述】:

我正在开发用于记录历史的软件。它本质上将是一个大时间线,因此您可以输入任何人、地点或事物以及日期,并将所有内容组织到一个 txt 文件中。 “Note”类是放入时间线的所有信息的父级。此类接受参数:self、*args、id='default'、start_date='iso_date'、end_date='iso_date'、loc='some location'。 我正在使用“*args”,以便您可以输入关于给定项目的任意数量的信息。 \n例如:

class Note(object):
    def __init__(self, *args, id="default", start_date=None, end_date=None, loc="default"):
        if start_date: start_date = date.fromisoformat(start_date)
        if end_date: end_date = date.fromisoformat(end_date)
        self.id = id.title()
        self.facts = [f for f in args]
        self.loc = loc

这太简单了,我无法打破它。当我专门为书籍创建一个子类时,问题就出现了。

class Book(Note):
    def __init__(self, *args, id='default', start_date=None, end_date=None, loc='default', author='Jane Doe'):
        super().__init__(self, *args, id=id, start_date=start_date, end_date=end_date, loc=loc)
        self.author = author

我必须在这里使用超级函数,以便它像往常一样初始化,但我仍然可以创建一个新变量“author”。这就是问题所在。

PS C:\Users\Max\projects\hist\Hist> py                                        Python 3.7.2 (tags/v3.7.2:9a3ffc0492, Dec 23 2018, 23:09:28) [MSC v.1916 64 bit (AMD64)] on win32
Type "help", "copyright", "credits" or "license" for more information.
>>> from objects import Book
>>>
>>> var = Book("It's about a whale.", "There is a captain.", id="Moby Dick", start_date="1851-10-18", loc="Pittsfield, Massachusetts")
>>>
>>> var.id
'Moby Dick'
>>>
>>> var.loc
'Pittsfield, Massachusetts'
>>>
>>> var.author
'Herman Melville'
>>>
>>> var.facts
[<objects.Book object at 0x0000010E08708160>, "It's about a whale.", 'There is a captain.']
>>>

不知何故,超级函数将子类作为参数,这是有道理的,但我还没有深入研究足够多的文档来找到规避问题的方法。我试过使用

super().__init__(self, args[1:], id=id, start_date=start_date, end_date=end_date, loc=loc)

制作这个:

>>> var.facts
[<objects.Book object at 0x0000017ADA3D8160>, ('There is a captain',)]

我不知道如何放弃这个论点。谁能帮帮我,我很笨。

【问题讨论】:

    标签: python-3.x class inheritance super args


    【解决方案1】:

    通过super()调用父类构造函数时,注意__init__方法已经是bound了。因此,就像调用任何其他绑定方法一样,self 部分是隐式传递的,不需要是显式参数。

    也就是说:

    class Parent: 
        pass                                                                         
    
    class Child(Parent): 
        def __init__(self): 
            print(super().__init__.__self__) 
    
    c = Child()  
    # prints <__main__.Child object at 0x105116e48>
    

    通常,您的代码可能在参数数量上出现某种 TypeError 失败,但由于您有 *args 并且没有类型验证所有 args 必须是字符串,它很高兴地采用额外的 self作为事实传递给超类时

    TL;DR 在调用 super() 时只需去掉显式的 self arg

    super().__init__(*args, id=id, start_date=start_date, end_date=end_date, loc=loc)
    

    【讨论】:

    • 你刚刚解决了一个问题,这让我在五分钟内死了一个小时。我同时对自己感到恼火,并且非常高兴它已修复!非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2022-09-22
    • 1970-01-01
    • 2014-04-10
    • 1970-01-01
    • 2016-10-16
    • 2018-03-10
    • 1970-01-01
    • 2017-02-05
    相关资源
    最近更新 更多