Python:スーパークラスからサブクラスを作成するにはどうすればよいですか?


86

Pythonでは、スーパークラスからサブクラスをどのように作成しますか?


3
Pythonはサブクラス化の方法を変更したため、2つの方法があり、それらが混在しないことに注意してください。混ぜるとエラーになります。違いを確認するために、この記事を読む:stackoverflow.com/questions/1713038/...
マーク・Lakata

回答:


89
# Initialize using Parent
#
class MySubClass(MySuperClass):
    def __init__(self):
        MySuperClass.__init__(self)

または、さらに良いことに、Pythonの組み込み関数の使用super()Python 2 / Python 3のドキュメントを参照)は、初期化のために親を呼び出すための少し良い方法かもしれません。

# Better initialize using Parent (less redundant).
#
class MySubClassBetter(MySuperClass):
    def __init__(self):
        super(MySubClassBetter, self).__init__()

または、super()クラス定義内でのみ機能する、のゼロ引数形式を使用することを除いて、上記とまったく同じです。

class MySubClassBetter(MySuperClass):
    def __init__(self):
        super().__init__()

6
OTOH、super特に新しいPythonプログラマー(Lutzなど)に対して警告する人もいます。私はそれを避けます。
eric

6
避ける唯一の理由supersuper、Pythonでの動作と、他の言語でのsuper/のparent動作の違いを理解していない場合です。確かに、これは他の言語から来た人々には明らかではありませんが、それが「注意」の対象となるとは結論付けません。それ機能します。動作が異なります。予期しない結果が得られることについて文句を言う前に、Pythonで実際に何が行われるかを読んでください。
TheAtomicOption 2017年

3
2つの違いは何ですか?
Tiwtiw


65

英雄的な小さな例:

class SuperHero(object): #superclass, inherits from default object
    def getName(self):
        raise NotImplementedError #you want to override this on the child classes

class SuperMan(SuperHero): #subclass, inherits from SuperHero
    def getName(self):
        return "Clark Kent"

class SuperManII(SuperHero): #another subclass
    def getName(self):
       return "Clark Kent, Jr."

if __name__ == "__main__":
    sm = SuperMan()
    print sm.getName()
    sm2 = SuperManII()
    print sm2.getName()

37
class MySubClass(MySuperClass):
    def __init__(self):
        MySuperClass.__init__(self)

        # <the rest of your custom initialization code goes here>

継承のセクションPythonドキュメントでは、より詳細にそれを説明します


5
__init__さらにコードを追加する場合にのみ、そのメソッドを定義する必要があります。それ以外の場合は、元のinitメソッドが使用されます(ただし、言及する価値があり、完全に有効なコードです)
dbr

2
質問は、さらにコードが追加される可能性があると想定するのに十分曖昧だったと思います。十分ではないよりも多くの情報を提供し、OPがそれを実装するときに別の質問に終わる方が良いです。:)
マットデューイ

15
class Class1(object):
    pass

class Class2(Class1):
    pass

Class2はClass1のサブクラスです


涼しい。これは私が実際に探していたものです。つまり、スーパーへの拡張/オーバーライドのないサブクラスです。
BuvinJ

9

上記の回答では、superは(キーワード)引数なしで初期化されます。ただし、多くの場合、それを実行したり、独自の「カスタム」引数を渡したりする必要があります。このユースケースを説明する例を次に示します。

class SortedList(list):
    def __init__(self, *args, reverse=False, **kwargs):
        super().__init__(*args, **kwargs)       # Initialize the super class
        self.reverse = reverse
        self.sort(reverse=self.reverse)         # Do additional things with the custom keyword arguments

これはサブクラスでlistあり、初期化されるreverseと、次のテストが示すように、キーワード引数で指定された方向にすぐにソートされます。

import pytest

def test_1():
    assert SortedList([5, 2, 3]) == [2, 3, 5]

def test_2():
    SortedList([5, 2, 3], reverse=True) == [5, 3, 2]

def test_3():
    with pytest.raises(TypeError):
        sorted_list = SortedList([5, 2, 3], True)   # This doesn't work because 'reverse' must be passed as a keyword argument

if __name__ == "__main__":
    pytest.main([__file__])

上の通過のおかげ*argsにはsuper、リストが初期化され、代わりにのみ、空であることの項目を移入することができます。(これreverseは、PEP 3102に準拠したキーワードのみの引数であることに注意してください)。


4

関数を使用してPythonでサブクラスを動的に作成する別の方法がありますtype()

SubClass = type('SubClass', (BaseClass,), {'set_x': set_x})  # Methods can be set, including __init__()

通常、メタクラスを操作するときにこのメソッドを使用します。低レベルの自動化を実行したい場合、Pythonがクラスを作成する方法が変わります。ほとんどの場合、この方法でそれを行う必要はありませんが、そうすることで、自分が何をしているかをすでに知っているはずです。





1
class BankAccount:

  def __init__(self, balance=0):
    self.balance = int(balance)

  def checkBalance(self): ## Checking opening balance....
    return self.balance

  def deposit(self, deposit_amount=1000): ## takes in cash deposit amount and updates the balance accordingly.
    self.deposit_amount = deposit_amount
    self.balance += deposit_amount
    return self.balance

  def withdraw(self, withdraw_amount=500): ## takes in cash withdrawal amount and updates the balance accordingly
    if self.balance < withdraw_amount: ## if amount is greater than balance return `"invalid transaction"`
        return 'invalid transaction'
    else:
      self.balance -= withdraw_amount
      return self.balance


class MinimumBalanceAccount(BankAccount): #subclass MinimumBalanceAccount of the BankAccount class

    def __init__(self,balance=0, minimum_balance=500):
        BankAccount.__init__(self, balance=0)
        self.minimum_balance = minimum_balance
        self.balance = balance - minimum_balance
        #print "Subclass MinimumBalanceAccount of the BankAccount class created!"

    def MinimumBalance(self):
        return self.minimum_balance

c = BankAccount()
print(c.deposit(50))
print(c.withdraw(10))

b = MinimumBalanceAccount(100, 50)
print(b.deposit(50))
print(b.withdraw(10))
print(b.MinimumBalance())

5
この回答は、それが何をするのかについての説明を含めるとさらに役立ちます
Grooveplex 2016年

4
このコードは問題の解決に役立つ場合がありますが、その理由や質問への回答方法については説明していません。この追加のコンテキストを提供すると、その長期的な教育的価値が大幅に向上します。回答を編集して、適用される制限や前提条件などの説明を追加してください。
Toby Speight 2016年

2
このコードスニペットは問題を解決する可能性がありますが、説明を含めると投稿の品質が向上します。あなたは将来読者のために質問に答えていることを忘れないでください、そしてそれらの人々はあなたのコード提案の理由を知らないかもしれません。
andreas 2016年

0

Pythonでのサブクラス化は次のように行われます。

class WindowElement:
    def print(self):
        pass

class Button(WindowElement):
    def print(self):
        pass

これは、クラスとサブクラスも含むPythonに関するチュートリアルです。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.