【问题标题】:proper way to store class instances in python app在 python 应用程序中存储类实例的正确方法
【发布时间】:2016-01-10 23:34:09
【问题描述】:

我试图了解在应用程序中存储类实例的最佳方式是什么,以便我访问属性权限并调用每个类方法权限。我想要使​​用 ORM 的解决方案,即 SqlAlchemy 并在最后添加 GUI。

假设我有笔记本课。还有一个 Note 类可以属于一个 Notebook。还有一个 Picture 类 - 它的实例可以出现在属于不同 Notebook 实例的多个 Notes 中。

现在我想到了下面的方法(我已经使它更简单/没有 ORM 只是为了得到这个想法):

class Notebook(object):
    def __init__(self):
        self.notesid=[]

    def view_notes(self,notes,pictures):
        for key,item in notes.items():
            if key in self.notesid:
                item.show(pictures)

class Note(object):
    def __init__(self,id,content,picture):
        self.id = id
        self.content = content
        self.picturesid = [picture.id]
    def show(self,pictures):
        print(self.id, self.content)
        for item in pictures:
            if item.id in self.picturesid:
                print(item)

class Picture(object):
    def __init__(self,id,path):
        self.id = id
        self.path = path
    def __str__(self):
        '''shows picture'''
        return "and here's picture %s" % (self.id)

# main program

notesdict={}
pictureslist=[]

notebook1=Notebook()
picture1 = Picture('p1','path/to/file')
note1=Note('n1','hello world',picture1)

notesdict[note1.id] = note1
pictureslist.append(picture1)
notebook1.notesid.append(note1.id)

notebook1.view_notes(notesdict,pictureslist)

我不确定这是否是正确的方法,因为即使在这个简单的示例中,我也需要将所有字典/实例容器放入 view_notes() 方法中。感觉必须有一种更简单/不易出错的方法。

我发现所有关于类创建的文章,但我找不到任何关于将它们放在一个应用程序和“类实例管理”中,存储多个类实例(包括一对多或多对- 许多链接同时)不同种类的类。

您能否通过使用上面的代码/文章/书籍的链接来指导我正确的思考/方法?

【问题讨论】:

  • 您能否更正主题行以匹配文本?您是否存储类或实例(对象)?区别很重要。 app 是什么意思?换句话说,在什么样的环境或操作系统中运行这段代码?
  • 我已按照建议更改了主题。不确定第二个问题的重要性,但对于“应用程序”,我的意思是主循环,我将在 Windows 上运行它(但如果是 Python 解释器,我猜操作系统无关紧要?)
  • 好的,“商店”是什么意思?是在“应用程序”运行时关注数据结构,还是长期存储对象(在文件或数据库中)?在 Python 中,列表和字典是收集对象的常规结构
  • 好的,让我们从非持久存储开始。这个字典/应该在哪里创建(基于我的例子)?在主循环中?我觉得这不是一个好主意,因为我需要将越来越多的列表传递给方法。是不是应该怎么做?我在某处读到这个列表可以在类中创建,即在笔记本类中,如果我理解正确,我会创建 self.notes 列表/字典。哪种方法更好?或者还有别的吗?
  • 如果逻辑上Notebook 包含Notes,那么我会给它一个可以包含Note 对象的属性(列表或字典),而不仅仅是它们的ID。而Notebook__init__ 可能会接受Notes 的列表。 Note 对象可以同时位于多个集合中,无论是全局列表还是多个 Notebooks 之一。

标签: python class storage instances


【解决方案1】:

好的,我明白了。 类实例可以存储在其他类实例中的列表/字典类型的属性中(例如Notebook实例中的Note实例)。

要记住的重要一点是实际存储的内容在该属性中是对位于 RAM 内存中某个地址下的实例的引用,而不是直接引用该实例。

考虑一下:

class Notebook(object):    
     def __init__(self, iteminstance):
        self.lista = [iteminstance]
     def show(self):
        print('Container1 list:')
        for item in self.lista:
            print(item.content)

class Binder(object):    
     def __init__(self, iteminstance):
        self.lista = [iteminstance]
     def show(self):
        print('Container2 list:')
        for item in self.lista:
            print(item.content)

class Note(object):    
    def __init__(self, txt):    
        self.content = txt    

# create Notebook instance and store Note instance in 'lista' list argument    
a=Notebook(Note(5))    
a.show()    

# assign the same Note instance to different container, Binder instance    
b=Binder(a.lista[0])    
b.show()

# check if both containers include the same object    
print(a.lista==b.lista)
>>>True

# change content of the Note instance via Notebook instance    
a.lista[0].content = 10

# check if content has changed in both Notebook and Binder instances 
a.show()    
b.show()

所以在第二次分配(给 Binder)之后,被复制的实际上只是对内存地址的引用。

因此,存储对象中的每个更改(在本例中为 Note)都可以通过每个 Container 访问。 我认为第二个分配会复制当前状态下的实例 - 但事实并非如此。

感谢 hpaulj 提出正确的问题! 为了进一步阅读,我需要查找我认为的“收藏类”。

【讨论】:

    猜你喜欢
    • 2019-05-11
    • 1970-01-01
    • 1970-01-01
    • 2012-04-27
    • 1970-01-01
    • 2023-04-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多