首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >音乐音符课- v2

音乐音符课- v2
EN

Code Review用户
提问于 2014-12-06 14:53:26
回答 1查看 139关注 0票数 0

音乐音符课第2版

代码语言:javascript
复制
#!/usr/bin/env python3

from string import ascii_uppercase
from string import ascii_lowercase


class Notes:
    octave_number = 7
    low_notes = ascii_uppercase[:octave_number]
    high_notes = ascii_lowercase[:octave_number]
    notes = low_notes + high_notes
    notes_number = range(octave_number * 2)
    notes_dict = dict(zip(notes, notes_number))
    numbers_dict = dict(zip(notes_number, notes))

    def __init__(self, _note):
        if not _note in Notes.notes:
            raise Exception("Not a valid note")
        self.note = _note
        self.note_number = Notes.notes_dict[self.note]

    def add(self, n):
        if (self.note in Notes.high_notes) and (n > 0):
            raise Exception("You can only add to low notes (ABCDEFG)")
        if (self.note in Notes.low_notes) and (n < 0):
            raise Exception("You can only subtract from notes (abcdefg)")
        if(abs(n) > Notes.octave_number):
            raise Exception("Maximum amount of increase or decrease is %d" % Notes.octave_number)


        new_number = self.note_number + n
        return Notes(Notes.numbers_dict[new_number])

测试:

代码语言:javascript
复制
x = Notes("A")
x.add(7).note
x = Notes("b")
x.add(-6).note

更改:

  • 移除minus
  • 扩展到两个八度音阶
  • add现在返回一个Notes对象
EN

回答 1

Code Review用户

回答已采纳

发布于 2014-12-06 15:13:15

您应该知道Python实现类行为的“神奇方法”,包括像__add____sub__这样的数值方法。这允许您编写例如note3 = note1 + note2,而不是note3 = note1.add(note2)。还有一些显示方法,包括__repr__,因此您可以轻松地查看实例。此外:

  • 类名应该是单数,因为只有一个注释,常量应该是UPPERCASE
  • 它更容易处理大写或小写,并相应地转换所有输入;
  • 您也可以通过self访问类属性,这使得继承更容易;
  • 您在note中检查__init__,但之后没有任何保护;以及
  • number可以根据需要根据note计算,而不是作为重复信息存储。

这里有一个有这些想法的替代实现。

代码语言:javascript
复制
#!/usr/bin/env python3

from string import ascii_uppercase

class Note:

    NOTE_COUNT = 7
    NUMBERS = dict(enumerate(ascii_uppercase[:NOTE_COUNT]))
    NOTES = {v: k for k, v in NUMBERS.items()}

    def __init__(self, note=None, number=None):
        if note is not None and note.upper() in self.NOTES:
            note = note.upper()
        elif number is not None and number in self.NUMBERS:
            note = self.NUMBERS[number]
        else:
            raise Exception("Not a valid note")
        self._note = note 

    def __repr__(self):
        return "Note({._note!r})".format(self)

    @property
    def number(self):
        return self.NOTES[self._note]

    @property
    def note(self):
        return self._note

    @note.setter
    def note(self, new_note):
        new_note = new_note.upper()
        if new_note not in self.NOTES:
            raise Exception("Not a valid note")
        self._note = new_note

    def __add__(self, other):
        try:
            num = other.number
        except AttributeError:
            num = other
        return Note(number=((self.number+num)%self.NOTE_COUNT))

    def __sub__(self, other):
        try:
            num = other.number
        except AttributeError:
            num = other
        return Note(number=((self.number-num)%self.NOTE_COUNT))

在使用中:

代码语言:javascript
复制
>>> B = Note("B")
>>> C = Note("C")
>>> B + C
Note('D') # not sure this addition makes sense, but it works!
>>> B.note = "X"
Traceback (most recent call last):
  File "<pyshell#38>", line 1, in <module>
    B.note = "X"
  File "<pyshell#34>", line 30, in note
    raise Exception("Not a valid note")
Exception: Not a valid note
>>> B.number
1

现在你所需要的就是八度音阶和意外!您还应该添加一些文档字符串,解释类做什么以及如何使用它。

票数 4
EN
页面原文内容由Code Review提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://codereview.stackexchange.com/questions/71868

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档