4

Ultimately looking to create a random music scale generator. I’m working on building classes for each mode and wanted to use major or minor scales as a True or False boolyan as a starting point.
Can someone tell me where I’m off with overriding this attribute for Mode2?

Here is my code:

class Mode():

    def __init__(self,title,major):
        self.title = title
        self.major= True


    def __str__(self):
        return "Title: {}, Major: {}".format(self.title,self.major)


Mode1 = Mode("Ionian", "Major")
print(Mode1)

class Mode2(Mode):
    def major(self):
        print(False)


Mode2 = Mode("Dorian", "Minor")
print(Mode2)
4
  • 1
    Methods get overridden, not attributes. If you want to change an attribute, just assign something else to it. Commented Jun 19, 2018 at 20:44
  • Python docs says: Python classes provide all the standard features of Object Oriented Programming: the class inheritance mechanism allows multiple base classes, a derived class can override any methods of its base class or classes, and a method can call the method of a base class with the same name. Commented Jun 19, 2018 at 20:54
  • your mode2 object is an instance of Mode, not Mode2. Is this intentional? Commented Jun 19, 2018 at 21:00
  • arent self.title = title self.major= True instance attributes ? Commented Jun 24, 2022 at 9:12

1 Answer 1

2

Try a more canonical design. First, I've altered your variables and attributes to reflect Pythonic naming conventions: major => ismajor, canonical case, etc.

With that, I've written a sub-class initialization that calls the parent's init, then makes desired alterations. I'm a bit confused about the major parameter, though: you ignore it and force the majority according to the class used. In any case, here's the result of my fiddling with your design:

class Mode():

    def __init__(self,title,ismajor):
        self.title = title
        self.ismajor= True

    def __str__(self):
        return "Title: {}, Major: {}".format(self.title,self.ismajor)


class Mode2(Mode):

    def __init__(self,title,ismajor):
        super().__init__(title, ismajor)
        self.ismajor= False


mode1 = Mode("Ionian", "Major")
print(mode1)

mode2 = Mode2("Dorian", "Minor")
print(mode2)

Output:

Title: Ionian, Major: True
Title: Dorian, Major: False

If I were doing this, I'd simplify even more: get rid of the different mode classes, and parameterize the one class:

legal_mode = [ 
    "Ionian",
    "Dorian",
    "Phrygian",
    "Lydian",
    "Mixolydian",
    "Aeolian",
    "Locrian"
]
stepping = [2, 2, 1, 2, 2, 2, 1]
major_mode = ["Ionian"]


class Mode():

    def __init__(self,title):
        self.title = title
        self.ismajor = title in major_mode
        tonic = legal_mode.index(title)
        self.stepping = stepping[tonic:] + stepping[:tonic]

    def __str__(self):
        return "Title: {}, Major: {}".format(self.title, self.ismajor)

    def scale_steps(self):
        return "Half-steps: {}".format(' '.join(str(c) for c in self.stepping))

mode1 = Mode("Ionian")
print(mode1)
print(mode1.scale_steps())

mode2 = Mode("Dorian")
print(mode2)
print(mode2.scale_steps())

Output:

Title: Ionian, Major: True
Half-steps: 2 2 1 2 2 2 1
Title: Dorian, Major: False
Half-steps: 2 1 2 2 2 1 2
Sign up to request clarification or add additional context in comments.

3 Comments

arent self.title = title self.major= True instance attributes ?
No, they are assignment statements. The attributes referenced are, indeed instance attributes. Since I did not say otherwise, I'm confused as to your question.
its about the post title: "Override class attributes in Python" that was about class and not instance attributes

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.