小编Eso*_*oid的帖子

理解__init_subclass__

我终于升级了我的python版本,我发现了添加的新功能.除此之外,我正在摸索新__init_subclass__方法.来自文档:

只要包含类被子类化,就会调用此方法.然后cls是新的子类.如果定义为普通实例方法,则此方法将隐式转换为类方法.

所以我开始尝试一下,按照文档中的示例:

class Philosopher:
    def __init_subclass__(cls, default_name, **kwargs):
        super().__init_subclass__(**kwargs)
        print(f"Called __init_subclass({cls}, {default_name})")
        cls.default_name = default_name

class AustralianPhilosopher(Philosopher, default_name="Bruce"):
    pass

class GermanPhilosopher(Philosopher, default_name="Nietzsche"):
    default_name = "Hegel"
    print("Set name to Hegel")

Bruce = AustralianPhilosopher()
Mistery = GermanPhilosopher()
print(Bruce.default_name)
print(Mistery.default_name)
Run Code Online (Sandbox Code Playgroud)

生成此输出:

Called __init_subclass(<class '__main__.AustralianPhilosopher'>, 'Bruce')
'Set name to Hegel'
Called __init_subclass(<class '__main__.GermanPhilosopher'>, 'Nietzsche')
'Bruce'
'Nietzsche'
Run Code Online (Sandbox Code Playgroud)

我知道这个方法是在子类定义之后调用的,但我的问题特别是关于这个特性的用法.我也阅读了PEP 487文章,但对我没什么帮助.这种方法在哪里有用?是为了:

  • 在创建时注册子类的超类?
  • 强制子类在定义时设置字段?

另外,我是否需要了解它__set_name__以充分理解其用法?

python metaclass class subclass python-3.6

41
推荐指数
4
解决办法
1万
查看次数

SAWarning:类型为&lt;Child&gt;的对象不在会话中,沿着“ Parent.children”的添加操作将不会继续

我一直在这个问题上停留,我不知道如何解决它。这是我的models.py文件:

models.py

class TripDetail(db.Model):
    """
    Base class for every table that contains info about a trip.
    """
    __abstract__ = True
    __bind_key__ = 'instructions'

    id = db.Column(db.Integer, primary_key=True)
    # list of fields    

class Overview(TripDetail):
    """
    Class that contains general information about a trip.
    """
    __tablename__ = 'overviews'
    __table_args__ = (
        db.ForeignKeyConstraint(['user_id', 'calendar_id'], ['calendars.user_id', 'calendars.id'], ondelete='CASCADE'),
    )  # constraints on other tables, omitted here
    user_id = db.Column(db.Integer, primary_key=True)
    calendar_id = db.Column(db.Integer, primary_key=True)
    calendar = db.relationship('Calendar', backref=db.backref('overviews', cascade='delete'), passive_deletes=True)
    # other …
Run Code Online (Sandbox Code Playgroud)

python sqlalchemy flask-sqlalchemy

1
推荐指数
1
解决办法
605
查看次数