Python 没有接受参数的init方法的类 从sqlalchemy导入创建引擎 从sqlalchemy导入序列 Base=声明性_Base() 列(整数,序列('user\u id\u seq'),主键=True) engine=create_engine('sqlite://:memory:',echo=True) 类用户(基本): __tablename_uu='users' id=列(整数,序列('user\u id\u seq'),主键=True) 名称=列(字符串(50)) 全名=列(字符串(50)) 昵称=列(字符串(50)) 定义报告(自我): 返回“”%( self.name、self.fullname、self.昵称) 类User1(基): __tablename_uu='users1' id=列(整数,序列('user\u id\u seq'),主键=True) 名称=列(字符串(50)) 全名=列(字符串(50)) 昵称=列(字符串(50)) 定义初始化(自我、姓名、全名、昵称): self.name=名称 self.fullname=fullname self.昵称=昵称 定义报告(自我): 返回“”%( self.name、self.fullname、self.昵称) ed_user=user(name='ed',fullname='ed Jones',昵称='edsnickname') ed_user=User1(name='edd',fullname='edd Jones',昵称='edsnick')

Python 没有接受参数的init方法的类 从sqlalchemy导入创建引擎 从sqlalchemy导入序列 Base=声明性_Base() 列(整数,序列('user\u id\u seq'),主键=True) engine=create_engine('sqlite://:memory:',echo=True) 类用户(基本): __tablename_uu='users' id=列(整数,序列('user\u id\u seq'),主键=True) 名称=列(字符串(50)) 全名=列(字符串(50)) 昵称=列(字符串(50)) 定义报告(自我): 返回“”%( self.name、self.fullname、self.昵称) 类User1(基): __tablename_uu='users1' id=列(整数,序列('user\u id\u seq'),主键=True) 名称=列(字符串(50)) 全名=列(字符串(50)) 昵称=列(字符串(50)) 定义初始化(自我、姓名、全名、昵称): self.name=名称 self.fullname=fullname self.昵称=昵称 定义报告(自我): 返回“”%( self.name、self.fullname、self.昵称) ed_user=user(name='ed',fullname='ed Jones',昵称='edsnickname') ed_user=User1(name='edd',fullname='edd Jones',昵称='edsnick'),python,sqlalchemy,Python,Sqlalchemy,我从sqlalchemy文档网站上获得了这段代码,我认为一切都很好,但是我在理解最后一行时遇到了一个问题,类user继承自基类,buy user类没有init方法来接受任何参数。能给我解释一下吗。。谢谢这两个类实现了与创建表相同的结果,但在第二个实例中,User1声明了一个init方法,因此显然表的创建发生在基类中,但是在第二个实例中,声明了类和实例变量。我想知道,如果基类没有从子类接收任何数据,它将如何创建表。也许下面的小片段有助于解释发生了什么: from sqlalchemy im

我从sqlalchemy文档网站上获得了这段代码,我认为一切都很好,但是我在理解最后一行时遇到了一个问题,类user继承自基类,buy user类没有init方法来接受任何参数。能给我解释一下吗。。谢谢这两个类实现了与创建表相同的结果,但在第二个实例中,User1声明了一个init方法,因此显然表的创建发生在基类中,但是在第二个实例中,声明了类和实例变量。我想知道,如果基类没有从子类接收任何数据,它将如何创建表。

也许下面的小片段有助于解释发生了什么:

    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')
结果

class A:
    def __init__(self, a):
        self.a = a

class B(A):

    def printme(self):
        print(self.a)

b = B(10)
b.printme()
B
继承类
A
,该类有一个
\uuuu init\uuuu
方法定义
self.A
,在创建实例
B
时调用该方法,如果子类(继承的类)没有类构造函数,则在类
B
方法
printme

中使用该方法(init方法),子类将调用父类的构造函数。但是,如果子类有构造函数,它将调用自己的构造函数

考虑以下示例:

没有构造函数的子类

10
class ParentClass:

    def __init__(self, parent_arg):
        self.parent_arg = parent_arg


class ChildClass(ParentClass):

    def child_method(self):
        print(self.parent_arg)


c = ChildClass(parent_arg="Test")
c.child_method() # Output: Test
具有构造函数的子类

10
class ParentClass:

    def __init__(self, parent_arg):
        self.parent_arg = parent_arg


class ChildClass(ParentClass):

    def child_method(self):
        print(self.parent_arg)


c = ChildClass(parent_arg="Test")
c.child_method() # Output: Test
要调用父类构造函数,请通过子类的构造函数传递父类的参数,并使用super()调用父类的构造函数

class ChildClass(ParentClass):

    def __init__(self, child_arg):
        self.child_arg = child_arg

    def child_method(self):
        print(self.child_arg) # Output: Child Test

        # This will throw an error since this attribute is created by the parent constructor
        print(self.parent_arg)

c = ChildClass(child_arg="Child Test")
c.child_method()

Python是一种非常动态的语言。有几种方法可以实现这一点。一种方法是从其超类继承,正如@vrevolverr所说。但不幸的是,这里不是这种情况。您可以通过运行
print(Base.\uuuuu init\uuuuuu是User.\uu init\uuuu)来确认这一点
,这将为您提供一个
False
。这意味着
用户。\uuu init\uuu
不是从
基继承的

另一个证据是,
print(用户中的“初始化”命令)
给出了
True
,这意味着
User
类有自己的
\uuuu init\uuuu
方法。这个方法只能由它的元类给出。所以答案就出来了。顺便说一句,在
sqlalchemy.ext.declarative
中,这个元类是
DeclarativeMeta

仅供参考。简单地说,元类可以在类的创建过程中执行某些操作。例如,向该类添加一个方法。这就是您的
\uuuu init\uuu
的来源


更新:

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

首先,
User1.\uuuu init\uuuu
是否生效?答案是否定的。尝试以下简单测试:

def init(self、name、fullname、昵称):
self.name=名称
self.fullname=fullname
self.昵称=昵称
类用户(基本):
...
__init_uu=init
打印(用户._uinit__;is init)#错误
您可以看到,您定义的
\uuuu init\uuu
方法已被替换

那么,如何实现这一“魔法”?见下文:

def init1(自):
通过
def初始化2(自身):
通过
类MyMeta(类型):
#你也可以在新的环境中这样做__
定义初始值(cls、*ARG、**kwargs):
cls.\uuuuu init\uuuuu=init2
类型.uuuu init_uuuuu(cls、*args、**kwargs)
类MyClass(元类=MyMeta):
__初始值=初始值1
打印(MyClass.uuu init_uuuu是init1)#错误
打印(MyClass.uuu init_uuuu是init2)#真
显然,表的创建是在基类中进行的

这是一种误解。模型类定义了表的结构,该表是在调用
Base.metadata.create\u all
或类似函数时创建的。这与类的任何实例的创建无关


创建模型类的实例-
user=user(…)
相当于在表上创建一行,而不是表本身。如果
\uuuuu init\uuuu
方法将值分配给类的属性,这些值将成为行值。如果未定义
\uuuu init\uuuu
函数,则声明性机制将调用默认构造函数(或作为
声明性\u base
的参数传递的函数)分配传递给模型构造函数的值。

如果我很好地理解了您的问题,您会想理解为什么用户类不包含
\uuuuuu init\uuuuuu
方法,但它能够接收参数,就像@snakecharmerb回答的那样,用户类能够接收
db.session.add_all([adams, ben, poolo])
db.session.commit()