将每个对象作为自身对象返回的方法

时间:2016-05-08 11:38:29

标签: python sqlite

我在Python中遇到列表问题。我希望我的Category有一个方法可以返回数据库中的所有类别。所以这是我的代码

class Category(Database)::

    # other methods here

    def find_by_id(self,  id_to_find ):
        sql_command = "SELECT * FROM categories WHERE id = :id LIMIT 1"
        self.cursor.execute( sql_command , data )
        return self.is_data_exists( self.cursor )

    # to check if cursor have at less one row
    def is_data_exists(self , cursor):
        result = cursor.fetchone()
        if result is None:
             return False
        else:
            # if data exists, we set the object with values
            self.id = data[0]
            self.name = data[1]
            return self


    def all(self):
        all_item = []
        self.cursor.execute( "SELECT id FROM categories" )

        for row in self.cursor.fetchall() :
            item = self.find_by_id(row[0])
            print( item.describe() )
            # problem here
            all_item.append(item)

        return all_item



Category().add("WEB")
Category().add("PYT")
Category().add("TEST")
Category().add("HELL")


for category in Category().all():
    print(category.describe())

所以print( item.describe() )返回:

Category #1 named *TEST*
Category #2 named *WEB*
Category #3 named *PYT*
Category #4 named *HELL*

Category().all()返回:

Category #4 named *HELL*
Category #4 named *HELL*
Category #4 named *HELL*
Category #4 named *HELL*

出了什么问题?看起来像self数组中的对象更改...

2 个答案:

答案 0 :(得分:2)

所以,让我们分解一下:

  • is_data_exists在设置一些成员变量后返回对self的引用。
  • find_by_id会返回is_data_exists返回的引用,因此也会引用self

然后:

item = self.find_by_id(row[0])

由于返回值的方式,这相当于item = self。 因此,all_item.append(item)会将self的引用添加到您的all_item列表中。

因此,您的列表实际上是[self, self, self, self]

问题的根源是进一步的。你有一个结构性问题。你定义:

class Category(Database):

但是,继承类意味着“X是Y”。在这里,您说“类别是数据库”

Category 数据库,因此这本质上是错误的。如果您需要一些常用方法,Category应该只是object,或者可能是Record。然后,对于数据库返回的每一行,您将实例化Category并将其添加到列表中。

但是,无论如何,除非你将它作为练习,否则使用适当的数据库抽象模块(如SQL炼金术),它将为您节省大量时间。

答案 1 :(得分:0)

我今天发现自己一招。实际上,我只需要调用Category()而不是self方法将“另一个自我”对象实例化到此对象中。结果如下:

class Category():
    database = Database(database_file_name)

    # other methods here

    @classmethod
    def all(cls):
        """return each categories présents in database"""
        cls.database.cursor.execute( "SELECT id FROM categories" )

        for id in self.cursor.fetchall() :
            yield Category.find_by_id(id[0])

我不知道这是不是很奇怪,但是它可以完成这项工作!谢谢你 spectras 的帮助!