5

私はPythonOOPを初めて使用し、ライブラリを管理するためのOOPプログラムを作成しようとしています。このコードは本からのものです。

action()このコードは期待どおりに機能していますが、特定のオプションを選択したときに対応する関数がどのように呼び出されるかを理解する必要があります。たとえば、関数を選択すると1show_notes関数を呼び出さなくても呼び出されます。

Menu.py

import sys
from notebook import Notebook, Note

class Menu:
    '''Display a menu and respond to choices when run.'''
    def __init__(self):
        self.notebook = Notebook()
        self.choices = {
                "1": self.show_notes,
                "2": self.search_notes,
                "3": self.add_note,
                "4": self.modify_note,
                "5": self.quit
                }

    def display_menu(self):
        print("""
Notebook Menu

1. Show all Notes
2. Search Notes
3. Add Note
4. Modify Note
5. Quit
""")

    def run(self):
        '''Display the menu and respond to choices.'''
        while True:
            self.display_menu()
            choice = input("Enter an option: ")
            action = self.choices.get(choice)
            if action:
                action()
            else:
                print("{0} is not a valid choice".format(choice))

    def show_notes(self, notes=None):
        if not notes:
            notes = self.notebook.notes
        for note in notes:
            print("{0}: {1}\n{2}".format(
                note.id, note.tags, note.memo))

    def search_notes(self):
        filter = input("Search for: ")
        notes = self.notebook.search(filter)
        self.show_notes(notes)

    def add_note(self):
        memo = input("Enter a memo: ")
        self.notebook.new_note(memo)
        print("Your note has been added.")

    def modify_note(self):
        id = input("Enter a note id: ")
        memo = input("Enter a memo: ")
        tags = input("Enter tags: ")
        if memo:
            self.notebook.modify_memo(id, memo)
        if tags:
            self.notebook.modify_tags(id, tags)

    def quit(self):
        print("Thank you for using your notebook today.")
        sys.exit(0)

if __name__ == "__main__":
    Menu().run()

notebook.py

import datetime

# Store the next available id for all new notes
last_id = 0

class Note:
    '''Represent a note in the notebook. Match against a
    string in searches and store tags for each note.'''


    def __init__(self, memo, tags=''):
        '''initialize a note with memo and optional
        space-separated tags. Automatically set the note's
        creation date and a unique id'''
        self.memo = memo
        self.tags = tags
        self.creation_date = datetime.date.today()
        global last_id
        last_id += 1
        self.id = last_id

    def match(self, filter):
        '''Determine if this note matches the filter
        text. Return True if it matches, False otherwise.

        Search is case sensitive and matches both text and
        tags.'''
        return filter in self.memo or filter in self.tags

class Notebook:

    '''Represent a collection of notes that can be tagged,
    modified, and searched.'''

    def __init__(self):
        '''Initialize a notebook with an empty list.'''
        self.notes = []

    def new_note(self, memo, tags=''):
        '''Create a new note and add it to the list.'''
        self.notes.append(Note(memo, tags))

    def _find_note(self, note_id):
        '''Locate the note with the given id.'''
        for note in self.notes:
            if str(note.id) == str(note_id):
                return note
        return None

    def modify_memo(self, note_id, memo):
        '''Find the note with the given id and change its
        memo to the given value.'''
        note = self._find_note(note_id)
        if note:
            note.memo = memo
            return True
        return False

    def modify_tags(self, note_id, tags):
        '''Find the note with the given id and change its
        tags to the given value.'''
        note = self._find_note(note_id)
        if note:
            note.tags = tags
            return True
        return False

    def search(self, filter):
        '''Find all notes that match the given filter
        string.'''
        return [note for note in self.notes if
                note.match(filter)]
4

4 に答える 4

6

関数とメソッドはそれ自体がオブジェクトです。したがって、dictには、次に呼び出すオブジェクトが含まれています。

つまり、self.choicesは、「1」、「2」などをキーとする辞書です。値はメソッドオブジェクトです。ディクショナリから値を取得すると、そのオブジェクト(「呼び出し可能」と呼ばれる)を取得して、に割り当てactionます。次に、そのオブジェクトを。で呼び出しますaction()

コードの重要な部分は次のとおりです。

 self.choices = {
            "1": self.show_notes,
            "2": self.search_notes,
            "3": self.add_note,
            "4": self.modify_note,
            "5": self.quit
            }

self.choices["1"]の値に評価されます。この値はself.show_notesに割り当てられaction、次に。で呼び出しますaction()

(余談ですが、サンプルコードのメニューはハードコーディングされていますが、メソッドにdocstringが含まれている場合は、実際には自動生成できます "\n".join("%s: %s" % (key, action.__doc__) for key, action in sorted(self.choices.iteritems())) 。10を超えるアイテムを含むメニューを適切に処理するには、キーを整数にするか、ワンライナーを拡張します。)

于 2012-08-08T18:22:17.337 に答える
2

self.choicesメソッドの辞書です。「1」を選択すると、これが発生します。

action = self.choices.get("1")  # action = self.show_notes

したがって、電話をかけるaction()ときは実際に電話をかけていますself.show_notes()

于 2012-08-08T18:24:55.427 に答える
1

ここで関数を呼び出します。

action = self.choices.get(choice)  # <--- get the function based on user input
if action:
    action()   # <--- call the function here

choiceが上記のコードと等しい場合は'1'、に割り当てself.show_notesてからaction呼び出します。

于 2012-08-08T18:22:37.297 に答える
0

のはdictでmenu.py::__init__self.choicesキーは整数で、値は関数です。ではmenu.py::run、choiceはstdinから入力され、self.choicesdictにキー入力するために使用されます。だからライン

action = self.choices.get(choice)

は、アクションをself.choicesの関数の1つに設定しています。次に、この関数を呼び出すことができます。

action()
于 2012-08-08T18:25:27.790 に答える