【问题标题】:Python: define object variable without initializationPython:在没有初始化的情况下定义对象变量
【发布时间】:2015-08-10 22:24:32
【问题描述】:

我正在尝试将我的代码从一个大函数重写为 oop。

如果我有这个,它会在session.add(a1) # Unresolved reference 上崩溃:

from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy import *
from sqlalchemy.orm import *

Base = declarative_base()

class Address(Base):
    __tablename__ = 'address'
    id = Column(Integer, primary_key=True)
    street = Column(String, nullable=False)
    city = Column(String, nullable=False)
    user = relationship('User', back_populates="address")

class Main():
    def __init__(self):
        engine = create_engine('mysql://test:test@localhost:3306/test', echo=False)
        Session = sessionmaker(bind=engine)
        session = Session()

    def insert(self):
        #   INSERT
        a1 = Address()
        a1.street = "Str 123"
        a1.city = "City WTF"

        session.add(a1) # Unresolved reference
        session.commit()

if __name__ == '__main__':
    Main().run()

我明白了。 session 是构造函数中的本地对象 (__init__)。

但是我怎样才能把对象“直接放到课堂上”呢? 在 Java 中,我会执行以下操作:

public class Main {
    Engine engine;
    Session session;
    public Main() {}
        engine = create_engine('mysql://test:test@localhost:3306/test', echo=False)
        session = sessionmaker(bind=engine)
    }
    private insert() {
        //...
        session.commit();
    }
}

如何在 python 中做到这一点? 对不起,愚蠢的问题,我是 python 新手。

--------------------- 编辑:

class Main():
    engine = None # What I write here? How declare uninitialized object?
    session = None # What I write here?
    def __init__(self):
        engine = create_engine('mysql://test:test@localhost:3306/test', echo=False)
        Session = sessionmaker(bind=engine)
        session = Session()

    def insert(self):
        #   INSERT
        a1 = Address()
        a1.street = "Str 123"
        a1.city = "City WTF"
        self.session.add(a1) # Is possible to call session without "self"?
        self.session.commit()

【问题讨论】:

  • 我不知道这是否是您的问题的直接原因,但您似乎在缩进中混合了制表符和空格。这可能会导致令人惊讶和不寻常的错误,因为解析器不会将制表符解释为四个空格,即使它在您的文本编辑器中看起来是这样的。请仅使用空格。
  • 只是让您知道 OOP 并不意味着“将所有内容都放在类中”。类应该是真实世界对象的数字表示。类不应该(在完美的世界中)只是函数的集合。
  • 我使用 PyCharm 自动代码格式 - 它修复了空格/制表符。
  • 您的解决方案是什么?将 cosntructor 的内容放到if __name__ == '__main__':?

标签: python oop constructor class-variables


【解决方案1】:

在 Java 中你会做 this.session = ...;在 Python 中是 self.session = ...

【讨论】:

    【解决方案2】:

    Main 类中的方法看起来像是属于 Address 类。

    engine = create_engine('mysql://test:test@localhost:3306/test', echo=False)
    session = sessionmaker(bind=engine)
    
    class Address(Base):
        __tablename__ = 'address'
        id = Column(Integer, primary_key=True)
        street = Column(String, nullable=False)
        city = Column(String, nullable=False)
        # you are missing some fields you'll need eventually
        state = Column(String, nullable=False)
        zip_code = Column(String, nullable=False)  # this can be an int if you don't have to worry about Canadian zips which have letters in them
        user = relationship('User', back_populates="address")
    
        def __init__(self, street, city, state, zip_code, user):
            self.street = street
            self.city = city
            self.state = state
            self.zip_code = zip_code
            self.user = user
    
        def insert(self, session):
            #   INSERT
            session.add(self)
            session.commit()
    

    您不应该将会话创建为类的一部分,因为这样每次实例化类时都会创建一个新会话。将会话保存在全局空间中,并将其作为参数传递给需要它的方法/函数(不要使用global)。

    现在一切都在正确的位置,你可以像这样使用它:

    from models import session, Address
    addr = Address('123 Test St.', 'Sometown', 'NY', '12345', some_user)
    addr.insert(session)
    

    【讨论】:

      【解决方案3】:

      您正在 __init__ 方法中初始化局部变量 session 并在此变量未知的方法中调用它。

      在这两种情况下都使用self.varialbe

      【讨论】:

        【解决方案4】:

        使用 self.session
        在会话中保存变量

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2017-04-22
          • 2011-07-18
          • 1970-01-01
          • 2013-09-12
          • 1970-01-01
          • 1970-01-01
          • 2015-01-26
          相关资源
          最近更新 更多