Python: 如何从超类创建子类?

在 Python 中,如何从超类创建子类?

187755 次浏览
class Subclass (SuperClass):
# Subclass stuff here
class Class1(object):
pass


class Class2(Class1):
pass

Class2 is a sub-class of Class1

You use:

class DerivedClassName(BaseClassName):

For details, see the Python docs, section 9.5.

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


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

The section on inheritance in the python documentation explains it in more detail

class Mammal(object):
#mammal stuff


class Dog(Mammal):
#doggie stuff

Subclassing in Python is done as follows:

class WindowElement:
def print(self):
pass


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

Here is a tutorial about Python that also contains classes and subclasses.

A heroic little example:

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())
    

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

Or, even better, the use of Python's built-in function, super() (see the Python 2/Python 3 documentation for it) may be a slightly better method of calling the parent for initialization:

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

Or, same exact thing as just above, except using the zero argument form of super(), which only works inside a class definition:

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

There is another way to make subclasses in python dynamically with a function type():

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

You usually want to use this method when working with metaclasses. When you want to do some lower level automations, that alters way how python creates class. Most likely you will not ever need to do it in this way, but when you do, than you already will know what you are doing.

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())

In the answers above, the super is initialized without any (keyword) arguments. Often, however, you would like to do that, as well as pass on some 'custom' arguments of your own. Here is an example which illustrates this use case:

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

This is a subclass of list which, when initialized, immediately sorts itself in the direction specified by the reverse keyword argument, as the following tests illustrate:

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__])

Thanks to the passing on of *args to super, the list can be initialized and populated with items instead of only being empty. (Note that reverse is a keyword-only argument in accordance with PEP 3102).

this is a small code:

# create a parent class


class Person(object):
def __init__(self):
pass


def getclass(self):
return 'I am a Person'
# create two subclass from Parent_class


class Student(Person):
def __init__(self):
super(Student, self).__init__()


def getclass(self):
return 'I am a student'




class Teacher(Person):
def __init__(self):
super(Teacher, self).__init__()


def getclass(self):
return 'I am a teacher'




person1 = Person()
print(person1.getclass())


student1 = Student()
print(student1.getclass())


teacher1 = Teacher()
print(teacher1.getclass())

show result:

I am a Person
I am a student
I am a teacher

A minor addition to @thompsongunner's answer.

To pass args to your superclass (parent), just use the function signature of the parent class:

class MySubClassBetter(MySuperClass):
def __init__(self, someArg, someKwarg="someKwarg"):
super().__init__(someArg, someKwarg=someKwarg)

You are calling the parent's __init__() method as if you are constructing any other class which is why you don't need to include self.