python 中关于派生 class 用法语法的继承
inheritance in python about derived class usage syntax
我有以下代码:
class person:
def __init__(self,fname,lname):
self.fname=fname
self.lname=lname
def printper(self):
return self.fname,self.lname
class emp:
def __init__(self,fname,lname,empno):
self.empno=empno
person.__init__(self,fname,lname)
def printper(self):
return self.empno,self.fname,self.lname
e1=emp("john","michael",20)
print(e1.printper())
# output: (20, 'john', 'michael')
我很困惑 - emp
没有继承自 person
,但是 代码仍然有效 。为什么?在 emp.__init__()
中调用 person.__init__()
似乎可以使代码正常工作。这就是必要的吗?写 class emp(person):
以获得派生的 class 实际上不是强制性的吗?
Python不关心提前检查类型、继承关系等。它只关心代码为 运行 时会发生什么。 This allows for what is called "duck typing":
class Employee:
def fired(self):
print("Oh no, I have to look for a new job")
class Gun:
def fired(self):
print("Bang! Did the bullet hit the target?")
for thing in [Employee(), Gun()]:
thing.fired()
class与Employee
和Gun
没有关系,fired
的目的无关紧要是完全不同的。列表中的两个对象都有一个名为 fired
的方法,因此代码可以正常运行。
与您的代码类似:
class emp:
def __init__(self,fname,lname,empno):
self.empno=empno
person.__init__(self,fname,lname)
如果我们调用 person.__init__
,那么这 只是我们在 person
class - [=58= 中找到的一个函数 ]不是我们在对象上查找的方法。这是因为我们在 .
的 left-hand 侧使用了 class,而不是实例。该函数将愉快地接受一个 emp
实例作为 self
的值——它 不关心 是否 self
是一个 person
实例。它是一个 user-defined 对象,因此设置 fname
和 lname
属性没有问题。
之后,printper
方法在 emp
实例上找到 fname
和 lname
属性就没有问题了——因为它们就在那里。
“那么,为什么还要费心去继承呢?”
因为即使这个“有效”,它仍然没有真正建立继承关系。这会产生一些后果:
super
不起作用 - __init__
调用必须明确说明要使用其他 class 什么,并且代码没有真正意义。从外部的角度来看,它设置了正确的属性纯属巧合。
默认情况下,isinstance
将不起作用。 emp
不在 __bases__
中,也不在 person
的 __mro__
中。
我有以下代码:
class person:
def __init__(self,fname,lname):
self.fname=fname
self.lname=lname
def printper(self):
return self.fname,self.lname
class emp:
def __init__(self,fname,lname,empno):
self.empno=empno
person.__init__(self,fname,lname)
def printper(self):
return self.empno,self.fname,self.lname
e1=emp("john","michael",20)
print(e1.printper())
# output: (20, 'john', 'michael')
我很困惑 - emp
没有继承自 person
,但是 代码仍然有效 。为什么?在 emp.__init__()
中调用 person.__init__()
似乎可以使代码正常工作。这就是必要的吗?写 class emp(person):
以获得派生的 class 实际上不是强制性的吗?
Python不关心提前检查类型、继承关系等。它只关心代码为 运行 时会发生什么。 This allows for what is called "duck typing":
class Employee:
def fired(self):
print("Oh no, I have to look for a new job")
class Gun:
def fired(self):
print("Bang! Did the bullet hit the target?")
for thing in [Employee(), Gun()]:
thing.fired()
class与Employee
和Gun
没有关系,fired
的目的无关紧要是完全不同的。列表中的两个对象都有一个名为 fired
的方法,因此代码可以正常运行。
与您的代码类似:
class emp:
def __init__(self,fname,lname,empno):
self.empno=empno
person.__init__(self,fname,lname)
如果我们调用 person.__init__
,那么这 只是我们在 person
class - [=58= 中找到的一个函数 ]不是我们在对象上查找的方法。这是因为我们在 .
的 left-hand 侧使用了 class,而不是实例。该函数将愉快地接受一个 emp
实例作为 self
的值——它 不关心 是否 self
是一个 person
实例。它是一个 user-defined 对象,因此设置 fname
和 lname
属性没有问题。
之后,printper
方法在 emp
实例上找到 fname
和 lname
属性就没有问题了——因为它们就在那里。
“那么,为什么还要费心去继承呢?”
因为即使这个“有效”,它仍然没有真正建立继承关系。这会产生一些后果:
super
不起作用 -__init__
调用必须明确说明要使用其他 class 什么,并且代码没有真正意义。从外部的角度来看,它设置了正确的属性纯属巧合。
默认情况下,isinstance
将不起作用。emp
不在__bases__
中,也不在person
的__mro__
中。