如果这些函数被标记为@staticmethod,那么它提供了什么价值——python
should these functions be marked @staticmethod, is so what value does this provide -- python
我正在构建一个简单的应用程序来创建和弦 sheet 对象,这些对象包含一个根音以及该根音的大三和弦和小三和弦中的所有音符。它还可以 return 反转。稍后,我将使用降音符并在基础 class 中添加更复杂的和弦(有一个和弦笔记本 class 用户可以将选定的和弦 sheet 存储在其中,但这无关紧要).我这样做只是为了练习我目前正在学习的概念。
get()方法和inversion()方法应该是静态方法吗?如果是这样,为什么?这提供了什么价值?
class Chord_Sheet:
notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
def __init__(self, root):
index = self.notes.index(root)
self.root = root
self.major = [self.notes[index], self.notes[(index+4)%12], self.notes[(index+7)%12]]
self.minor = [self.notes[index], self.notes[(index+3)%12], self.notes[(index+7)%12]]
#self.perfect_fifth = [self.notes[index], self.notes[(index+x)%12], self.notes[(index+x)%12]]
#self.diminished_fifth = [self.notes[index], self.notes[(index+x)%12], self.notes[(index+x)%12]]
#self.major_seventh = []
#self.minor_seventh = []
#self.diminished_seventh = []
def get_root(self): #static?
return "Root: {}".format(self.root)
def get_major(self): #static?
return "Major Chord: {} {} {} or {} {} {}".format(self.major[0], self.major[1], self.major[2], self.major[0], self.major[2], self.major[1])
def get_minor(self): #static?
return "Minor Chord: {} {} {} or {} {} {}".format(self.minor[0], self.minor[1], self.minor[2], self.minor[0], self.minor[2], self.minor[1])
def first_inverted_major(self): #static?
return "First Major Inversion: {} {} {} or {} {} {}".format(self.major[1], self.major[2], self.major[0], self.major[1], self.major[0], self.major[2])
def first_inverted_minor(self): #static?
return "First Minor Inversion: {} {} {} or {} {} {}".format(self.minor[1], self.minor[2], self.minor[0], self.minor[1], self.minor[0], self.minor[2])
def second_inverted_major(self): #static?
return "Second Major Inversion: {} {} {} or {} {} {}".format(self.major[2], self.major[0], self.major[1], self.major[2], self.major[1], self.major[0])
def second_inverted_minor(self): #static?
return "Second Minor Inversion: {} {} {} or {} {} {}".format(self.minor[2], self.minor[0], self.minor[1], self.minor[2], self.minor[1], self.minor[0])
来自this post:
This type of method takes neither a self nor a cls parameter (but of
course it’s free to accept an arbitrary number of other parameters).
Therefore a static method can neither modify object state nor class
state. Static methods are restricted in what data they can access -
and they’re primarily a way to namespace your methods.
意味着有时有一个属于 Chord_Sheet
命名空间的 semi-related 函数很有用(即使用 Chord_Sheet.foo()
调用的函数 foo
)。它不能与对象状态交互,因为它不将 self
作为参数,因此不能使用 self.root
等
这是您的代码分为实例方法、静态方法和功能方法。
显然有trade-offs ...评论已经所以我不会打死马。 ;)
# with INSTANCE methods
################################################################################
class ChordSheet:
notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
def __init__(self, root):
index = self.notes.index(root)
self.root = root
self.major = [self.notes[index], self.notes[(index + 4) % 12],
self.notes[(index + 7) % 12]]
self.minor = [self.notes[index], self.notes[(index + 3) % 12],
self.notes[(index + 7) % 12]]
# self.perfect_fifth = [self.notes[index], self.notes[(index+x)%12], self.notes[(index+x)%12]]
# self.diminished_fifth = [self.notes[index], self.notes[(index+x)%12], self.notes[(index+x)%12]]
# self.major_seventh = []
# self.minor_seventh = []
# self.diminished_seventh = []
def get_root(self): # static?
return "Root: {}".format(self.root)
def get_major(self): # static?
return "Major Chord: {} {} {} or {} {} {}".format(self.major[0],
self.major[1],
self.major[2],
self.major[0],
self.major[2],
self.major[1])
def get_minor(self): # static?
return "Minor Chord: {} {} {} or {} {} {}".format(self.minor[0],
self.minor[1],
self.minor[2],
self.minor[0],
self.minor[2],
self.minor[1])
def first_inverted_major(self): # static?
return "First Major Inversion: {} {} {} or {} {} {}".format(
self.major[1], self.major[2], self.major[0], self.major[1],
self.major[0], self.major[2])
def first_inverted_minor(self): # static?
return "First Minor Inversion: {} {} {} or {} {} {}".format(
self.minor[1], self.minor[2], self.minor[0], self.minor[1],
self.minor[0], self.minor[2])
def second_inverted_major(self): # static?
return "Second Major Inversion: {} {} {} or {} {} {}".format(
self.major[2], self.major[0], self.major[1], self.major[2],
self.major[1], self.major[0])
def second_inverted_minor(self): # static?
return "Second Minor Inversion: {} {} {} or {} {} {}".format(
self.minor[2], self.minor[0], self.minor[1], self.minor[2],
self.minor[1], self.minor[0])
# with STATIC methods
################################################################################
class ChordSheetAlt:
@staticmethod
def get_root(root):
return "Root: {}".format(root)
@staticmethod
def get_major(root, notes):
index = notes.index(root)
major = [notes[index], notes[(index + 4) % 12],
notes[(index + 7) % 12]]
return "Major Chord: {} {} {} or {} {} {}".format(major[0],
major[1],
major[2],
major[0],
major[2],
major[1])
@staticmethod
def get_minor(root, notes):
index = notes.index(root)
minor = [notes[index], notes[(index + 3) % 12],
notes[(index + 7) % 12]]
return "Minor Chord: {} {} {} or {} {} {}".format(minor[0],
minor[1],
minor[2],
minor[0],
minor[2],
minor[1])
@staticmethod
def first_inverted_major(root, notes):
index = notes.index(root)
major = [notes[index], notes[(index + 4) % 12],
notes[(index + 7) % 12]]
return "First Major Inversion: {} {} {} or {} {} {}".format(
major[1], major[2], major[0], major[1],
major[0], major[2])
@staticmethod
def first_inverted_minor(root, notes):
index = notes.index(root)
minor = [notes[index], notes[(index + 3) % 12],
notes[(index + 7) % 12]]
return "First Minor Inversion: {} {} {} or {} {} {}".format(
minor[1], minor[2], minor[0], minor[1],
minor[0], minor[2])
@staticmethod
def second_inverted_major(root, notes):
root = root
index = notes.index(root)
major = [notes[index], notes[(index + 4) % 12],
notes[(index + 7) % 12]]
return "Second Major Inversion: {} {} {} or {} {} {}".format(
major[2], major[0], major[1], major[2],
major[1], major[0])
@staticmethod
def second_inverted_minor(root, notes):
index = notes.index(root)
minor = [notes[index], notes[(index + 3) % 12],
notes[(index + 7) % 12]]
return "Second Minor Inversion: {} {} {} or {} {} {}".format(
minor[2], minor[0], minor[1], minor[2],
minor[1], minor[0])
# refactor ChordSheetAlt class to FUNCTIONAL
# since its chock full of static methods, i.e. stand-alone functions
# might as well convert fully to FUNCTIONAL
################################################################################
def get_root_chord(root):
# add type/constraint/error, etc. handling logic
return "Root: {}".format(root)
def get_index(root, notes):
# add type/constraint/error, etc. handling logic
return notes.index(root)
def compose_major(index, notes):
# add type/constraint/error, etc. handling logic
return [notes[index], notes[(index + 4) % 12],notes[(index + 7) % 12]]
def compose_minor(index, notes):
# add type/constraint/error, etc. handling logic
return [notes[index], notes[(index + 3) % 12],notes[(index + 7) % 12]]
def get_major_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
major = compose_major(index, notes)
return "Major Chord: {} {} {} or {} {} {}".format(major[0],
major[1],
major[2],
major[0],
major[2],
major[1])
def get_minor_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
minor = compose_minor(index, notes)
return "Minor Chord: {} {} {} or {} {} {}".format(minor[0],
minor[1],
minor[2],
minor[0],
minor[2],
minor[1])
def first_inverted_major_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
major = compose_major(index, notes)
return "First Major Inversion: {} {} {} or {} {} {}".format(major[1],
major[2],
major[0],
major[1],
major[0],
major[2])
def first_inverted_minor_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
minor = compose_minor(index, notes)
return "First Minor Inversion: {} {} {} or {} {} {}".format(minor[1],
minor[2],
minor[0],
minor[1],
minor[0],
minor[2])
def second_inverted_major_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
major = compose_major(index, notes)
return "Second Major Inversion: {} {} {} or {} {} {}".format(major[2],
major[0],
major[1],
major[2],
major[1],
major[0])
def second_inverted_minor_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
minor = compose_minor(index, notes)
return "Second Minor Inversion: {} {} {} or {} {} {}".format(minor[2],
minor[0],
minor[1],
minor[2],
minor[1],
minor[0])
if __name__ == '__main__':
print('\nclass with instance methods:')
print('-'*79)
sheet = ChordSheet(root='D')
print(sheet.get_root())
print(sheet.get_major())
print(sheet.get_minor())
print(sheet.first_inverted_major())
print(sheet.first_inverted_minor())
print(sheet.second_inverted_major())
print(sheet.second_inverted_minor())
# STATIC
print('\nclass with static methods:')
print('-'*79)
mynotes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
print(ChordSheetAlt.get_root(root='D'))
print(ChordSheetAlt.get_major(root='D',notes=mynotes))
print(ChordSheetAlt.get_minor(root='D',notes=mynotes))
print(ChordSheetAlt.first_inverted_major(root='D',notes=mynotes))
print(ChordSheetAlt.first_inverted_minor(root='D',notes=mynotes))
print(ChordSheetAlt.second_inverted_major(root='D',notes=mynotes))
print(ChordSheetAlt.second_inverted_minor(root='D',notes=mynotes))
# STATIC
print('\nclass with static methods (arbitrary input list):')
print('-'*79)
mynotes = [i for i in range(15)]
print(ChordSheetAlt.get_root(root=2))
print(ChordSheetAlt.get_major(root=2,notes=mynotes))
print(ChordSheetAlt.get_minor(root=2,notes=mynotes))
print(ChordSheetAlt.first_inverted_major(root=2,notes=mynotes))
print(ChordSheetAlt.first_inverted_minor(root=2,notes=mynotes))
print(ChordSheetAlt.second_inverted_major(root=2,notes=mynotes))
print(ChordSheetAlt.second_inverted_minor(root=2,notes=mynotes))
# FUNCTIONAL
print('\nfunctional programming style:')
print('-'*79)
mynotes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
root = 'D'
root_and_notes = (root, mynotes)
print(get_root_chord(root))
print(get_major_chords(*root_and_notes))
print(get_minor_chords(*root_and_notes))
print(first_inverted_major_chords(*root_and_notes))
print(first_inverted_minor_chords(*root_and_notes))
print(second_inverted_major_chords(*root_and_notes))
print(second_inverted_minor_chords(*root_and_notes))
我正在构建一个简单的应用程序来创建和弦 sheet 对象,这些对象包含一个根音以及该根音的大三和弦和小三和弦中的所有音符。它还可以 return 反转。稍后,我将使用降音符并在基础 class 中添加更复杂的和弦(有一个和弦笔记本 class 用户可以将选定的和弦 sheet 存储在其中,但这无关紧要).我这样做只是为了练习我目前正在学习的概念。
get()方法和inversion()方法应该是静态方法吗?如果是这样,为什么?这提供了什么价值?
class Chord_Sheet:
notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
def __init__(self, root):
index = self.notes.index(root)
self.root = root
self.major = [self.notes[index], self.notes[(index+4)%12], self.notes[(index+7)%12]]
self.minor = [self.notes[index], self.notes[(index+3)%12], self.notes[(index+7)%12]]
#self.perfect_fifth = [self.notes[index], self.notes[(index+x)%12], self.notes[(index+x)%12]]
#self.diminished_fifth = [self.notes[index], self.notes[(index+x)%12], self.notes[(index+x)%12]]
#self.major_seventh = []
#self.minor_seventh = []
#self.diminished_seventh = []
def get_root(self): #static?
return "Root: {}".format(self.root)
def get_major(self): #static?
return "Major Chord: {} {} {} or {} {} {}".format(self.major[0], self.major[1], self.major[2], self.major[0], self.major[2], self.major[1])
def get_minor(self): #static?
return "Minor Chord: {} {} {} or {} {} {}".format(self.minor[0], self.minor[1], self.minor[2], self.minor[0], self.minor[2], self.minor[1])
def first_inverted_major(self): #static?
return "First Major Inversion: {} {} {} or {} {} {}".format(self.major[1], self.major[2], self.major[0], self.major[1], self.major[0], self.major[2])
def first_inverted_minor(self): #static?
return "First Minor Inversion: {} {} {} or {} {} {}".format(self.minor[1], self.minor[2], self.minor[0], self.minor[1], self.minor[0], self.minor[2])
def second_inverted_major(self): #static?
return "Second Major Inversion: {} {} {} or {} {} {}".format(self.major[2], self.major[0], self.major[1], self.major[2], self.major[1], self.major[0])
def second_inverted_minor(self): #static?
return "Second Minor Inversion: {} {} {} or {} {} {}".format(self.minor[2], self.minor[0], self.minor[1], self.minor[2], self.minor[1], self.minor[0])
来自this post:
This type of method takes neither a self nor a cls parameter (but of course it’s free to accept an arbitrary number of other parameters).
Therefore a static method can neither modify object state nor class state. Static methods are restricted in what data they can access - and they’re primarily a way to namespace your methods.
意味着有时有一个属于 Chord_Sheet
命名空间的 semi-related 函数很有用(即使用 Chord_Sheet.foo()
调用的函数 foo
)。它不能与对象状态交互,因为它不将 self
作为参数,因此不能使用 self.root
等
这是您的代码分为实例方法、静态方法和功能方法。 显然有trade-offs ...评论已经所以我不会打死马。 ;)
# with INSTANCE methods
################################################################################
class ChordSheet:
notes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
def __init__(self, root):
index = self.notes.index(root)
self.root = root
self.major = [self.notes[index], self.notes[(index + 4) % 12],
self.notes[(index + 7) % 12]]
self.minor = [self.notes[index], self.notes[(index + 3) % 12],
self.notes[(index + 7) % 12]]
# self.perfect_fifth = [self.notes[index], self.notes[(index+x)%12], self.notes[(index+x)%12]]
# self.diminished_fifth = [self.notes[index], self.notes[(index+x)%12], self.notes[(index+x)%12]]
# self.major_seventh = []
# self.minor_seventh = []
# self.diminished_seventh = []
def get_root(self): # static?
return "Root: {}".format(self.root)
def get_major(self): # static?
return "Major Chord: {} {} {} or {} {} {}".format(self.major[0],
self.major[1],
self.major[2],
self.major[0],
self.major[2],
self.major[1])
def get_minor(self): # static?
return "Minor Chord: {} {} {} or {} {} {}".format(self.minor[0],
self.minor[1],
self.minor[2],
self.minor[0],
self.minor[2],
self.minor[1])
def first_inverted_major(self): # static?
return "First Major Inversion: {} {} {} or {} {} {}".format(
self.major[1], self.major[2], self.major[0], self.major[1],
self.major[0], self.major[2])
def first_inverted_minor(self): # static?
return "First Minor Inversion: {} {} {} or {} {} {}".format(
self.minor[1], self.minor[2], self.minor[0], self.minor[1],
self.minor[0], self.minor[2])
def second_inverted_major(self): # static?
return "Second Major Inversion: {} {} {} or {} {} {}".format(
self.major[2], self.major[0], self.major[1], self.major[2],
self.major[1], self.major[0])
def second_inverted_minor(self): # static?
return "Second Minor Inversion: {} {} {} or {} {} {}".format(
self.minor[2], self.minor[0], self.minor[1], self.minor[2],
self.minor[1], self.minor[0])
# with STATIC methods
################################################################################
class ChordSheetAlt:
@staticmethod
def get_root(root):
return "Root: {}".format(root)
@staticmethod
def get_major(root, notes):
index = notes.index(root)
major = [notes[index], notes[(index + 4) % 12],
notes[(index + 7) % 12]]
return "Major Chord: {} {} {} or {} {} {}".format(major[0],
major[1],
major[2],
major[0],
major[2],
major[1])
@staticmethod
def get_minor(root, notes):
index = notes.index(root)
minor = [notes[index], notes[(index + 3) % 12],
notes[(index + 7) % 12]]
return "Minor Chord: {} {} {} or {} {} {}".format(minor[0],
minor[1],
minor[2],
minor[0],
minor[2],
minor[1])
@staticmethod
def first_inverted_major(root, notes):
index = notes.index(root)
major = [notes[index], notes[(index + 4) % 12],
notes[(index + 7) % 12]]
return "First Major Inversion: {} {} {} or {} {} {}".format(
major[1], major[2], major[0], major[1],
major[0], major[2])
@staticmethod
def first_inverted_minor(root, notes):
index = notes.index(root)
minor = [notes[index], notes[(index + 3) % 12],
notes[(index + 7) % 12]]
return "First Minor Inversion: {} {} {} or {} {} {}".format(
minor[1], minor[2], minor[0], minor[1],
minor[0], minor[2])
@staticmethod
def second_inverted_major(root, notes):
root = root
index = notes.index(root)
major = [notes[index], notes[(index + 4) % 12],
notes[(index + 7) % 12]]
return "Second Major Inversion: {} {} {} or {} {} {}".format(
major[2], major[0], major[1], major[2],
major[1], major[0])
@staticmethod
def second_inverted_minor(root, notes):
index = notes.index(root)
minor = [notes[index], notes[(index + 3) % 12],
notes[(index + 7) % 12]]
return "Second Minor Inversion: {} {} {} or {} {} {}".format(
minor[2], minor[0], minor[1], minor[2],
minor[1], minor[0])
# refactor ChordSheetAlt class to FUNCTIONAL
# since its chock full of static methods, i.e. stand-alone functions
# might as well convert fully to FUNCTIONAL
################################################################################
def get_root_chord(root):
# add type/constraint/error, etc. handling logic
return "Root: {}".format(root)
def get_index(root, notes):
# add type/constraint/error, etc. handling logic
return notes.index(root)
def compose_major(index, notes):
# add type/constraint/error, etc. handling logic
return [notes[index], notes[(index + 4) % 12],notes[(index + 7) % 12]]
def compose_minor(index, notes):
# add type/constraint/error, etc. handling logic
return [notes[index], notes[(index + 3) % 12],notes[(index + 7) % 12]]
def get_major_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
major = compose_major(index, notes)
return "Major Chord: {} {} {} or {} {} {}".format(major[0],
major[1],
major[2],
major[0],
major[2],
major[1])
def get_minor_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
minor = compose_minor(index, notes)
return "Minor Chord: {} {} {} or {} {} {}".format(minor[0],
minor[1],
minor[2],
minor[0],
minor[2],
minor[1])
def first_inverted_major_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
major = compose_major(index, notes)
return "First Major Inversion: {} {} {} or {} {} {}".format(major[1],
major[2],
major[0],
major[1],
major[0],
major[2])
def first_inverted_minor_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
minor = compose_minor(index, notes)
return "First Minor Inversion: {} {} {} or {} {} {}".format(minor[1],
minor[2],
minor[0],
minor[1],
minor[0],
minor[2])
def second_inverted_major_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
major = compose_major(index, notes)
return "Second Major Inversion: {} {} {} or {} {} {}".format(major[2],
major[0],
major[1],
major[2],
major[1],
major[0])
def second_inverted_minor_chords(root, notes):
# add type/constraint/error, etc. handling logic
index = get_index(root, notes)
minor = compose_minor(index, notes)
return "Second Minor Inversion: {} {} {} or {} {} {}".format(minor[2],
minor[0],
minor[1],
minor[2],
minor[1],
minor[0])
if __name__ == '__main__':
print('\nclass with instance methods:')
print('-'*79)
sheet = ChordSheet(root='D')
print(sheet.get_root())
print(sheet.get_major())
print(sheet.get_minor())
print(sheet.first_inverted_major())
print(sheet.first_inverted_minor())
print(sheet.second_inverted_major())
print(sheet.second_inverted_minor())
# STATIC
print('\nclass with static methods:')
print('-'*79)
mynotes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
print(ChordSheetAlt.get_root(root='D'))
print(ChordSheetAlt.get_major(root='D',notes=mynotes))
print(ChordSheetAlt.get_minor(root='D',notes=mynotes))
print(ChordSheetAlt.first_inverted_major(root='D',notes=mynotes))
print(ChordSheetAlt.first_inverted_minor(root='D',notes=mynotes))
print(ChordSheetAlt.second_inverted_major(root='D',notes=mynotes))
print(ChordSheetAlt.second_inverted_minor(root='D',notes=mynotes))
# STATIC
print('\nclass with static methods (arbitrary input list):')
print('-'*79)
mynotes = [i for i in range(15)]
print(ChordSheetAlt.get_root(root=2))
print(ChordSheetAlt.get_major(root=2,notes=mynotes))
print(ChordSheetAlt.get_minor(root=2,notes=mynotes))
print(ChordSheetAlt.first_inverted_major(root=2,notes=mynotes))
print(ChordSheetAlt.first_inverted_minor(root=2,notes=mynotes))
print(ChordSheetAlt.second_inverted_major(root=2,notes=mynotes))
print(ChordSheetAlt.second_inverted_minor(root=2,notes=mynotes))
# FUNCTIONAL
print('\nfunctional programming style:')
print('-'*79)
mynotes = ["C", "C#", "D", "D#", "E", "F", "F#", "G", "G#", "A", "A#", "B"]
root = 'D'
root_and_notes = (root, mynotes)
print(get_root_chord(root))
print(get_major_chords(*root_and_notes))
print(get_minor_chords(*root_and_notes))
print(first_inverted_major_chords(*root_and_notes))
print(first_inverted_minor_chords(*root_and_notes))
print(second_inverted_major_chords(*root_and_notes))
print(second_inverted_minor_chords(*root_and_notes))