如何遍历类的所有实例?

时间:2019-06-03 04:53:12

标签: python python-3.x

所以我知道以前已经有人问过这个问题,但是我找不到我的问题的答案,所有的答案都让我更加困惑。

因此,我创建了一个名为Books的类,该类将文件的位置和文件名作为输入,并具有一种称为countwords的方法,该方法对文件的单词进行计数。

我创建了此类的一堆实例(它们被称为吗?),但是我不想在所有实例上迭代CountWords方法。这是我的代码:

class Books():
    def __init__(self, path, fullname):
        self.path     = path
        self.fullname = fullname

    def count_words(self):
        try:
            with open(self.path + self.fullname, encoding='utf-8') as f:
                contents = f.read()
        except FileNotFoundError:
            print(f"Sorry, the file {self.fullname} doesn't exist.")
        else:
            words     = contents.split()
            num_words = len(words)
            print(f"The file {self.fullname} has about {num_words}" 
                  f"words.")             

alice        = Books("text_files/", 'alice.txt')
siddharta    = Books("text_files/", 'siddhartha.txt')
mobydick     = Books('text_files/', 'moby_dick.txt')
little_women = Books('text_files/', 'little_women.txt')

我不会写这样的东西:

for book in Books.list():
    book.count_words()

并获得:

 The file alice.txt has about 29465 words. 
 The file siddhartha.txt has about 1500 words.
 The file moby_dick.txt has about 215830 words. 
 The file little_women.txt has about 189079 words. 

打印与Books()类关联的所有实例的单词计数,如何实现呢?谢谢!

编辑: 我尝试了不同的方法,但这是我现在正在使用的方法:

  1. 第一个是导入weakref(不知道这是干什么的。)。

  2. 然后在课程开始时添加一个空列表。

  3. 之后使用:def init末尾的self .__ class__LISTNAME_append(weakref.proxy(self))

  4. 然后,您可以遍历LISTNAME。

代码:

# 1 
import weakref

class Book():
  # 2
  book_list = []
  def __init__(self, path, fullname):
      self.path = path
      self.fullname = fullname
      # 3
      self.__class__.book_list.append(weakref.proxy(self))

  def count_words(self):
      try:
          with open(self.path + self.fullname, encoding='utf-8') as f:
              contents = f.read()
      except FileNotFoundError:
          print(f"Sorry, the file {self.fullname} doesn't exist.")
      else:
          words = contents.split()
          num_words = len(words)
          print(f"The file {self.fullname} has about {num_words} "
                f"words. ")

alice = Book("text_files/", 'alice.txt')

siddharta = Book("text_files/", 'siddhartha.txt')

mobydick = Book('text_files/', 'moby_dick.txt')

little_women = Book('text_files/', 'little_women.txt')

# 4
for book in Book.book_list:
  book.count_words()

4 个答案:

答案 0 :(得分:2)

建议您先 定义数据,然后再从该数据创建实例集合,而不是让类保留对已创建的所有实例的引用。

例如:

book_paths = [('text_files/', 'alice.txt'),
              ('text_files/', 'siddharta.txt'),
              ('text_files/', 'moby_dick.txt'),
              ('text_files/', 'little_women.txt')]

books = []

for path, name in book_paths:
    book = Books(path, name)
    books.append(book)
    book.count_words()

您还可以稍后在books上进行迭代,以执行所需的任何操作。另一种方法是使用list理解:

books = [Books(path, name) for path, name in book_paths]

for book in books:
    book.count_words()

答案 1 :(得分:1)

您要做的就是创建一个类变量,该变量将在实例化实例时存储书籍信息。

然后公开一个类级方法,该方法将在调用Books.list时返回此列表。

这是相同的代码

class Books(object):
    _books_list = list()
    def __init__(self, path, fullname):
        self.path = path
        self.fullname = fullname
        self._books_list.append(self.path + self.fullname)

    def count_words(self):
        try:
            with open(self.path + self.fullname, encoding='utf-8') as f:
                contents = f.read()
        except FileNotFoundError:
            print(f"Sorry, the file {self.fullname} doesn't exist.")
        else:
            words = contents.split()
            num_words = len(words)
            print(f"The file {self.fullname} has about {num_words}"
                  f"words.")
    @classmethod
    def list():
        return self._books_list
alice = Books("text_files/", 'alice.txt')
siddharta = Books("text_files/", 'siddhartha.txt')
mobydick = Books('text_files/', 'moby_dick.txt')
little_women = Books('text_files/', 'little_women.txt')

答案 2 :(得分:1)

那是解决问题的错误方法。

我建议您改为创建一个类字典,以文件名作为键:

代替:

alice = Books("text_files/", 'alice.txt')
siddharta = Books("text_files/", 'siddhartha.txt')
mobydick = Books('text_files/', 'moby_dick.txt')
little_women = Books('text_files/', 'little_women.txt')

这样做:

books_dict = {name:Books('text_files/',name+".txt") for name in ["alice","siddhartha","moby_dick","little_women"}

现在您有一个Books个实例的字典。您现在可以像这样迭代它:

for book_name,book_instance in books_dict.items():
    print(book_name,book_instance)

如果您要“取消注册”实例,只需执行以下操作:

books_dict.pop("alice")

最好不要为x个实例创建x个变量。使用联合结构。

答案 3 :(得分:1)

从您的变量来看,通过命名类Book可能更容易理解:

class Book():
    def __init__(self, path, fullname):
        self.path = path
        self.fullname = fullname

    def count_words(self):
        try:
            with open(self.path + self.fullname, encoding='utf-8') as f:
                contents = f.read()
        except FileNotFoundError:
            print(f"Sorry, the file {self.fullname} doesn't exist.")
        else:
            words = contents.split()
            num_words = len(words)
            print(f"The file {self.fullname} has about {num_words}" 
                  f"words.")    

按照您的描述制作书籍实例

alice = Book("text_files/", 'alice.txt')
siddharta = Book("text_files/", 'siddhartha.txt')
mobydick = Book('text_files/', 'moby_dick.txt')
little_women = Book('text_files/', 'little_women.txt')

并将它们添加到引用为books的列表中:

books = [alice, siddhartha, mobydick, little_women]

然后,您可以遍历每本书上调用count_words方法的列表