gpt4 book ai didi

python - 没有 init 方法接受参数的类

转载 作者:行者123 更新时间:2023-12-05 08:18:09 25 4
gpt4 key购买 nike

    from sqlalchemy import create_engine

from sqlalchemy import Sequence
Base = declarative_base()
Column(Integer, Sequence('user_id_seq'), primary_key=True)
engine = create_engine('sqlite:///:memory:', echo=True)
class User(Base):
__tablename__ = 'users'
id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
name = Column(String(50))
fullname = Column(String(50))
nickname = Column(String(50))

def __repr__(self):
return "<User(name='%s', fullname='%s', nickname='%s')>" % (
self.name, self.fullname, self.nickname)

class User1(Base):
__tablename__ = 'users1'
id = Column(Integer, Sequence('user_id_seq'), primary_key=True)
name = Column(String(50))
fullname = Column(String(50))
nickname = Column(String(50))

def __init__(self, name, fullname, nickname):
self.name = name
self.fullname = fullname
self.nickname = nickname


def __repr__(self):
return "<User(name='%s', fullname='%s', nickname='%s')>" % (
self.name, self.fullname, self.nickname)

ed_user = User(name='ed', fullname='Ed Jones', nickname='edsnickname')
ed_user = User1(name='edd', fullname='Edd Jones', nickname='edsnick')

我从 sqlalchemy 文档网站上获取了这段代码,我认为一切正常,但我对最后一行的理解有问题,类 user 从基类继承,购买用户类没有初始化其他接受任何参数的方法。有人可以向我解释一下吗..谢谢。这两个类实现了创建表的相同结果,但在第二个实例中,User1 声明了一个 init 方法,因此显然表的创建发生在基类中,但在第二个实例声明了类和实例变量我想知道如果基类没有从子类接收任何数据,它将如何创建表。

最佳答案

Python 是一种非常动态的语言。有几种方法可以实现这一点。正如@vrevolverr 所说,一个是从其父类(super class)继承。但不幸的是,这里不是这种情况。您可以通过运行 print(Base.__init__ is User.__init__) 来确认,这会给您一个 False。这意味着 User.__init__ 不是从 Base 继承的。

另一个证据是 print('__init__' in User.__dict__) 给你 True,这意味着 User 类有它自己的__init__ 方法。而这个方法只能由它的元类给定。于是答案就出来了。顺便说一句,在你的例子中,这个元类是 sqlalchemy.ext.declarative 中的 DeclarativeMeta

仅供引用。简单地说,元类可以在类的创建过程中做一些事情。比如给这个类添加一个方法。这是您的 __init__ 的来源。


更新:

我原来的回答也解决了你的第二个问题。但我还是想补充一些意见。

首先,User1.__init__是否生效?答案是不。试试这个简单的测试:

def init(self, name, fullname, nickname):
self.name = name
self.fullname = fullname
self.nickname = nickname

class User(Base):
...
__init__ = init

print(User.__init__ is init) # False

可以看到你定义的__init__方法已经被替换了。

那么,如何施展这个“魔法”呢?见下文:

def init1(self):
pass

def init2(self):
pass

class MyMeta(type):
# You can also do this in __new__
def __init__(cls, *args, **kwargs):
cls.__init__ = init2
type.__init__(cls, *args, **kwargs)


class MyClass(metaclass=MyMeta):
__init__ = init1

print(MyClass.__init__ is init1) # False
print(MyClass.__init__ is init2) # True

关于python - 没有 init 方法接受参数的类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63992923/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com