【问题标题】:Class in class in class in python, how to share informationpython中的类中类,如何共享信息
【发布时间】:2016-07-12 09:14:20
【问题描述】:

我正在尝试在 python 中使用 peewee 为数据库创建一个类。由于 peewee 在模型中使用了一个名为 meta 的类,这导致了嵌套类。我的问题是,如何在 Meta 类中定义数据库(=db)?有没有更好的办法?

import peewee as pe

    class DataBase():
        class SensorType(pe.Model):
            name = pe.CharField(max_length=255, unique=True)

            class Meta:
                database = db

    def ___init___(self,filename='sensors.db'):
        db = pe.SqliteDatabase(filename)
        db.connect()
        db.create_tables([self.SensorType],safe=True)

    def add_sensor(self,typeName):
        type, created = self.SensorType.get_or_create(name=typeName)
        return type, created

    def get_sensors(self):
        return self.SensorType.select().order_by(self.SensorType.name)


if __name__ == '__main__':

    myDb = DataBase()
    myDb.add_sensor('Test')

    for type in myDb.get_sensors():     
        print(type.name) 

我发现在我的主类的__init__ 函数中定义类是可行的。但这可能不是首选方法。

import peewee as pe

class DataBase():
    def __init__(self,filename='sensors.db'):        
       db = pe.SqliteDatabase(filename)
       db.connect()

        class SensorType(pe.Model):
           typename = pe.CharField(max_length=255, unique=True)
           class Meta:
              database = db             

       self.SensorType = SensorType          
       db.create_tables([self.SensorType],safe=True)


    def add_sensor_type(self,typeName):
       type, created = self.SensorType.get_or_create(typename=typeName)
       return type, created

    def get_sensor_types(self):
       return self.SensorType.select()

if __name__ == '__main__':

    myDb = DataBase()
    myDb.add_sensor_type('Test')

    for type in myDb.get_sensor_types():     
        print(type.id, type.typename)

【问题讨论】:

  • 更好的方法?是的,不要使用嵌套类。
  • 我同意,这似乎不是一个好方法。在我的示例中,您对如何避免它有任何提示吗?

标签: python database peewee


【解决方案1】:

尝试继承,而不是嵌套类。 This post 提供了一些关于如何在 Python 中使用继承和元类的相当不错的信息。

查看peewee 的快速入门示例,这样的方法对您有用吗?

import peewee

class BaseModel(peewee.Model):            
    def __init__(self, db):
        super(BaseModel, self).__init__()
        Meta.database = db

    class Meta:
        database = None

class SensorType(BaseModel):
    def __init__(self, db):
        super(SensorType, self).__init__(db)

    name = peewee.CharField(max_length=255, unique=True)

class DataBase():
    def __init__(self, filename='sensors.db'):
        self.db = peewee.SqliteDatabase(filename)
        self.sensor_type = SensorType(self.db)
        self.db.connect()
        self.db.create_tables([self.sensor_type], safe=True)

    def add_sensor(self, typeName):
        type, created = self.sensor_type.get_or_create(name=typeName)
        return type, created

    def get_sensors(self):
        return self.sensor_type.select().order_by(self.sensor_type.name)

if __name__ == '__main__':
    db = DataBase()

    db.add_sensor('Test')
    [print(type.name) for type in db.get_sensors()]

弄乱模型的__init__ 方法,看看是否可以在初始化时传递数据库实例。

我会远离在方法中定义一个类。

我希望这会有所帮助!

【讨论】:

  • 感谢您的帮助,以及关于继承的帖子的链接。很好的阅读。
  • 运行此代码时出现以下错误:NameError: name 'Meta' is not defined - 它不应该是一个工作示例?
【解决方案2】:

我最终使用了 peewee 文档中的 this approach。它有效,我避免使用嵌套类:

import peewee as pe
database = pe.SqliteDatabase(None)

class BaseModel(pe.Model):
    class Meta:
        database = database

class SensorType(BaseModel):
    name = pe.CharField(max_length=255, unique=True)

class DataBase():
    def __init__(self, filename='sensors.db'):
        database.init(filename)
        self.sensor_type = SensorType()
        database.connect()
        database.create_tables([self.sensor_type], safe=True)        

if __name__ == '__main__':
    db = DataBase('test.db')

【讨论】:

  • 我不确定您对全局变量的感受。很高兴您找到了适合您的解决方案!
猜你喜欢
  • 2011-04-15
  • 1970-01-01
  • 1970-01-01
  • 2013-06-10
  • 2018-08-02
  • 1970-01-01
  • 2011-02-27
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多