[英]Python class inheritance/Logic gate & circuit example
我目前正在自学Python,正在阅读“使用算法和数据结构解决问题”(Brad Miller,David Ranum)。 我偶然发现了继承的基本示例。 尽管我可以看到它的作用,但是我需要解释一下它是如何工作的。 代码如下:
class LogicGate:
def __init__(self,n):
self.name = n
self.output = None
def getName(self):
return self.name
def getOutput(self):
self.output = self.performGateLogic()
return self.output
class BinaryGate(LogicGate):
def __init__(self,n):
LogicGate.__init__(self,n)
self.pinA = None
self.pinB = None
def getPinA(self):
if self.pinA == None:
return int(input("Enter Pin A input for gate "+self.getName()+"-->"))
else:
return self.pinA.getFrom().getOutput()
def getPinB(self):
if self.pinB == None:
return int(input("Enter Pin B input for gate "+self.getName()+"-->"))
else:
return self.pinB.getFrom().getOutput()
def setNextPin(self,source):
if self.pinA == None:
self.pinA = source
else:
if self.pinB == None:
self.pinB = source
else:
print("Cannot Connect: NO EMPTY PINS on this gate")
class AndGate(BinaryGate):
def __init__(self,n):
BinaryGate.__init__(self,n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a==1 and b==1:
return 1
else:
return 0
class OrGate(BinaryGate):
def __init__(self,n):
BinaryGate.__init__(self,n)
def performGateLogic(self):
a = self.getPinA()
b = self.getPinB()
if a ==1 or b==1:
return 1
else:
return 0
class UnaryGate(LogicGate):
def __init__(self,n):
LogicGate.__init__(self,n)
self.pin = None
def getPin(self):
if self.pin == None:
return int(input("Enter Pin input for gate "+self.getName()+"-->"))
else:
return self.pin.getFrom().getOutput()
def setNextPin(self,source):
if self.pin == None:
self.pin = source
else:
print("Cannot Connect: NO EMPTY PINS on this gate")
class NotGate(UnaryGate):
def __init__(self,n):
UnaryGate.__init__(self,n)
def performGateLogic(self):
if self.getPin():
return 0
else:
return 1
class Connector:
def __init__(self, fgate, tgate):
self.fromgate = fgate
self.togate = tgate
tgate.setNextPin(self)
def getFrom(self):
return self.fromgate
def getTo(self):
return self.togate
def main():
g1 = AndGate("G1")
g2 = AndGate("G2")
g3 = OrGate("G3")
g4 = NotGate("G4")
c1 = Connector(g1,g3)
c2 = Connector(g2,g3)
c3 = Connector(g3,g4)
print(g4.getOutput())
main()
我主要对Connector
类__init__
的tgate.setNextPin(self)
语句感到怀疑。 是方法调用吗? 如果是这样,为什么在UnaryGate
和BinaryGate
类(self, source)
的setNexPin
函数实际需要两个参数时,为什么只用一个参数调用它? fromgate
变量如何最终成为source
参数? 该语句实际上“初始化”了什么吗?
接下来让我困扰的事情是,例如,当我在声明g4.getOutput()
print(type(g4))
之前print(type(g4))
,我得到了<class '__main__.OrGate'>
,但是当g4.getOutput()
启动并运行时开始呼叫对方,调用点getPin
功能,如果我把print (self.pinA)
之前return self.pinA.getFrom().getOutput()
我得到的<__main__.Connector object at 0x2b387e2f74d0>
虽然self.Pin
是g4
OrGate
实例中的变量。 一个类实例中的一个变量如何才能成为不继承它的另一类的对象? 它与setNextPin()
函数有关吗?
有人可以向我解释这一点,因为我是OOP的新手,并对这段代码感到困惑。 谢谢。
关于第一个问题, tgate.setNextPin(self)
是一个方法调用。 tgate
是一个对象,可能是其中一种门类型的实例。 当您访问instance.method
,Python为您提供了一个“绑定方法”对象,该对象的工作原理类似于函数,但是在实际调用该实例时将其作为第一个参数。 因此, tgate.setNextPin(self)
实际上是在调用type(tgate).setNextPin(tgate, self)
您的第二个问题似乎反映了对什么是属性的误解。 不需要对象的属性为其自己的类型。 在各个LogicGate
亚类,所述pin
/ pinA
/ pinB
属性或者将是None
(信令用户应该被提示输入一输入值)或一个实例Connector
(或别的东西与getFrom
方法)。 这些值都不是LogicGate
实例。
至于您看到的Connector
实例的来源,它将是您创建的c1
到c3
值之一。 Connector
实例使用您在第一个问题中询问的setNextPin call
,将自身安装到其tgate
参数的引脚上。 我无法真正说出您正在查看的g4
门,因为它似乎与示例代码的main()
函数中创建的g4
变量不同(它是另一种类型),但我怀疑它的工作原理是设计,这有点令人困惑。 尝试通过g4.pinA
访问pinX
属性,而不是在方法内部进行检查,这样可能会减少一些混乱。
以下是一些带有输出的代码,这些代码应该可以帮助您更好地理解事物:
# create a few gates
g1 = AndGate("G1")
g2 = OrGate("G2")
# at this point, no connectors have been hooked up, so all pinX attrs are None:
print("G1 pins:", g1.pinA, g1.pinB) # "None, None"
print("G2 pins:", g2.pinA, g2.pinB) # "None, None"
# test that the gates work independently of each other:
print("G1 output:", g1.getOutput()) # will prompt for two inputs, then print their AND
print("G2 output:", g2.getOutput()) # will prompt for two inputs, then print their OR
# create a connection between the gates
c1 = Connector(g1, g2) # connects output of g1 to first available pin (pinA) of g2
# we can see that g2.pinA has changed
print("G2 pins after connection:", g2.pinA, g2.pinB)
# "<__main__.Connector object at SomeHexAddress>, None"
# now, if we get g2's output, it will automatically request g1's output via the Connector
print("G2 output:", g2.getOutput())
# will prompt for 2 G1 inputs, and one G2 input and print (G1_A AND G1_B) OR G2_B
如果您想更多地使用这些类,则可能要向某些或所有类中添加__str__
(和/或__repr__
)方法。 Python使用__str__
在必要时将类的实例转换为字符串(例如,将其作为参数传递给print
或str.format
)。 这是Connector
的快速__str__
实现:
def __str__(self):
return "Connector between {} and {}".format(self.fgate.name, self.tgate.name)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.