1

我是 Python 新手,我开始学习代码结构的基础知识。我有一个基本的应用程序,我正在我的 Github 上开发

对于我的简单应用程序,我创建了一个基本的“Evernote-like”服务,允许用户创建和编辑笔记列表。在早期的设计中,我有一个 Note 对象和一个 Notepad 对象,它实际上是一个笔记列表。目前,我有以下文件结构:

Notes.py
| 
|------ Notepad (class)
|------ Note (class)

根据我目前的理解和实现,这转化为具有 Notepad 类和 Note 类的“Notes”模块,所以当我进行导入时,我说的是“从 Notes 导入 Notepad / 从 Notes 导入 Note”。

这是正确的方法吗?我觉得,出于 Java 的习惯,我应该有一个 Notes 文件夹和两个类作为单独的文件。

我的目标是了解最佳实践是什么。

4

2 回答 2

4

只要类很小,就将它们放入一个文件中。如有必要,您仍然可以稍后移动它们。实际上,较大的项目具有相当深的层次结构但向用户展示更扁平的层次结构是很常见的。因此,如果您稍后移动内容,但notes.Note即使类Note移动得更深,仍然希望保留,只需导入note.path.to.module.Note即可notes,用户可以从那里获取它。你不必这样做,但你可以。因此,即使您稍后改变主意但想保留 API,也没有问题。

于 2013-05-28T01:59:03.507 回答
1

我自己一直在使用类似的应用程序。我不能说这是最好的方法,但它对我很有帮助。当用户发出请求(http 请求,这是一个 webapp)时,这些类旨在与数据库(上下文)进行交互。

# -*- coding: utf-8 -*-
import json
import datetime

class Note ():
    """A note. This class is part of the data model and is instantiated every
    time there access to the database"""
    def __init__(self, noteid = 0, note = "", date = datetime.datetime.now(), context = None):
        self.id = noteid
        self.note = note
        self.date = date
        self.ctx = context #context holds the db connection and some globals

    def get(self):
        """Get the current object from the database. This function needs the
        instance to have an id"""
        if id == 0:
            raise self.ctx.ApplicationError(404, ("No note with id 0 exists"))
        cursor = self.ctx.db.conn.cursor()
        cursor.execute("select note, date from %s.notes where id=%s" % 
                       (self.ctx.db.DB_NAME, str(self.id)))
        data = cursor.fetchone()
        if not data:
            raise self.ctx.ApplicationError(404, ("No note with id " 
                                                 + self.id + " was found"))
        self.note = data[0]
        self.date = data[1]
        return self

    def insert(self, user):
        """This function inserts the object to the database. It can be an empty
        note. User must be authenticated to add notes (authentication handled
        elsewhere)"""
        cursor = self.ctx.db.conn.cursor()
        query = ("insert into %s.notes (note, owner) values ('%s', '%s')" % 
                       (self.ctx.db.DB_NAME, str(self.note), str(user['id'])))
        cursor.execute(query)
        return self

    def put(self):
        """Modify the current note in the database"""
        cursor = self.ctx.db.conn.cursor()
        query = ("update %s.notes set note = '%s' where id = %s" % 
                 (self.ctx.db.DB_NAME, str(self.note), str(self.id)))
        cursor.execute(query)
        return self

    def delete(self):
        """Delete the current note, by id"""
        if self.id == 0:
            raise self.ctx.ApplicationError(404, "No note with id 0 exists")
        cursor = self.ctx.db.conn.cursor()
        query = ("delete from %s.notes where id = %s" % 
                 (self.ctx.db.DB_NAME, str(self.id)))
        cursor.execute(query)

    def toJson(self):
        """Returns a json string of the note object's data attributes"""
        return json.dumps(self.toDict())

    def toDict(self):
        """Returns a dict of the note object's data attributes"""
        return {
                "id" : self.id,
                "note" : self.note,
                "date" : self.date.strftime("%Y-%m-%d %H:%M:%S")
                }


class NotesCollection():
    """This class handles the notes as a collection"""
    collection = []
    def get(self, user, context):
        """Populate the collection object and return it"""
        cursor = context.db.conn.cursor()
        cursor.execute("select id, note, date from %s.notes where owner=%s" % 
                       (context.db.DB_NAME, str(user["id"])))
        note = cursor.fetchone()
        while note:
            self.collection.append(Note(note[0], note[1],note[2]))
            note = cursor.fetchone()
        return self

    def toJson(self):
        """Return a json string of the current collection"""
        return json.dumps([note.toDict() for note in self.collection])

我个人将 python 用作“完成”语言,并且不会为细节烦恼。这显示在上面的代码中。但是有一条建议:python 中没有私有变量或方法,所以不要费心去创建它们。让您的生活更轻松,快速编码,完成任务

使用示例:

class NotesCollection(BaseHandler):
    @tornado.web.authenticated
    def get(self):
        """Retrieve all notes from the current user and return a json object"""
        allNotes = Note.NotesCollection().get(self.get_current_user(), settings["context"])
        json = allNotes.toJson()
        self.write(json)

    @protected
    @tornado.web.authenticated
    def post(self):
        """Handles all post requests to /notes"""
        requestType = self.get_argument("type", "POST")
        ctx = settings["context"]
        if requestType == "POST":

            Note.Note(note = self.get_argument("note", ""), 
                      context = ctx).insert(self.get_current_user())
        elif requestType == "DELETE":
            Note.Note(id = self.get_argument("id"), context = ctx).delete()
        elif requestType == "PUT":
            Note.Note(id = self.get_argument("id"),
                              note = self.get_argument("note"),
                              context = ctx).put()
        else:
            raise ApplicationError(405, "Method not allowed")

通过使用装饰器,我从主代码中获得了用户身份验证和错误处理。这使它更清晰,更容易维护。

于 2013-05-28T01:57:32.390 回答