我是OOPS的新手
我想知道何时初始化父类实例P
并且我想初始化子类实例C
喜欢
class A(object):
def __init__(self):
print "A created"
P = A()
class B(A):
def __init__(self):
print super((B), self).__init__ # Q1: How to get "A created" from parent class?
print self.__class__.__name__
print super(B, self).__class__.__name__
Q2:现在,如果我创建一个实例z = B()
,我想创建z
作为P
的子实例,即只有早期才会创建z
实例P
存在。
如果添加到属性中,P
的属性应该向下流到z
w / data。
基本上,如果z
不存在,则不应创建P
y = B() iff x = A()
有没有办法做到这一点?
我这样做是因为我正在创建一个程序,其中将在各种上下文中创建类A
的多个实例,例如
Mathematics = A()
English = A()
Now,
Algebra = B() iff Mathematics = A()
And
Grammar = B() iff English = A()
是否有自检者检查?我的意思是怎么做的?
Q2更新: 另一种问题是,有没有办法在创建实例时检查B类,以检查A类的实例并获取特定实例数据? 就像在B类中检查由A类组成的实例然后选择一个并从该实例的属性获取数据到创建B类的实例
另外
z = B()
<bound method B.__init__ of <__main__.B object at 0x000000000791DB38>>
B
super #Q3: I thought it would print `A`. WHY NOT?
答案 0 :(得分:3)
您未在__init__
中致电B
。使用函数的名称只是为您提供该函数对象。 __init__()
实际执行函数后的括号。
super(B, self)
返回一个类,而不是一个对象(这是有意义的 - 一个类没有超级实例,它有一个超类),所以你然后在该类上调用__class__
,结果在意想不到的结果。您在__class__
上使用self
,因为self
是该类的实例。
class B(A):
def __init__(self):
super(B, self).__init__()
print type(self).__name__
print super(B, self).__name__
请注意,我使用type()
而不是访问__class__
- 使用内置函数比直接访问魔术值更好。它更具可读性,并允许特殊功能。
答案 1 :(得分:1)
class A(object):
def __init__(self):
print "A created"
class B(A):
def __init__(self):
super(B, self).__init__() # Q1: How to get "A created" from parent class?
b = B()
--output:--
A created
我想创建z作为P的子实例,即z应该只是 如果存在早期实例P,则创建。和P的属性 应该向下流到z w /数据(如果有的话添加到属性中)。
1)你为什么称z为P的'子实例'?你说,只有当P的实例存在时,使z成为'子实例'与创建z是等价的(“即”)。怎么会这样?这个“子实例”语言来自哪里?你是否也说整数10是20的“子实例”,如果20已存在?
2)P不是一个类,因此P的任何属性都不会流到任何地方。
UPDATE2)
class A(object):
def __init__(self, name):
self.name = name
class B(A):
def __init__(self, anA, age):
super(B, self).__init__(anA.name)
self.age = age
existingA = {}
a = A("Sally")
existingA["Sally"] = a
a = A("George")
existingA["George"] = a
x = "Sally"
if x in existingA:
b = B(existingA[x], 30)
print b.name, b.age
--output:--
Sally 30
答案 2 :(得分:0)
基于阅读更新的Q2并再次查看Q1,听起来您对课程有一个基本的误解,以及他们可以为您做些什么。 (这是有道理的,因为你说你是“OOP新手”。)
除非我知道您熟悉哪种非 -OOP语言,否则我将在这里违反术语,但我将使用C示例并故意掩盖一大堆问题,并声称您的class A
与struct A
类似,而您的class B
只是struct B
包含整个struct A
:
struct A {
int x, y; /* ... etc */
};
struct B {
struct A a;
int z;
}
如果您创建B
的新实例,则无法使其a
成员的类型更改,它始终是实际的{{ 1}}。如果有A
(类型或实例),则无关紧要,struct A2
的内容只包含一个B
。
听起来你想要的根本不是子类,而只是一个普通的成员,(在C中)更像是有一些指针其他对象,而不是用身体结合它:
A
(在C中,至少有一个指针,如果它是class A1(object):
def __init__(self):
pass
def about(self):
print 'I am an A1'
class A2(object):
def __init__(self):
pass
def about(self):
print 'I am an A2'
class B(object):
def __init__(self, connected_to = None):
self.connected_to = connected_to
def about(self):
print 'I am a B'
if self.connected_to is not None:
print '... and I am connected to a %s:' % type(self.connected_to)
self.connected_to.about() # and ask it to describe itself
else:
print '... and I am connected to no one!'
- 意味着您可以指向您需要的任何类型,或者根本不指向任何类型,就像上面的void *
一样connected_to B
而不是某些A1或A2,或者实际上只要有None
的任何东西。)
鉴于上述情况,您可以这样做:
.about()
当然,你可以让>>> B(A1()).about()
I am a B
... and I am connected to a <class '__main__.A1'>:
I am an A1
>>> B(A2()).about()
I am a B
... and I am connected to a <class '__main__.A2'>:
I am an A2
>>> B().about()
I am a B
... and I am connected to no one!
>>>
的{{1}}自己找到A1或A2(如果存在),如果明确地传递它不是你想要的。
当然,这会模糊做为您做的(子)类。根据上面的示例,您可以创建一个类B
,然后创建一个子类__init__
,也可以创建另一个子类Maths(object)
。另外,您可以创建一个类Algebra(Maths)
和一个子类Topology(Maths)
,以及另一个子类HumanLanguage(object)
。但是你不会创建一个子类English(HumanLanguage)
,而Russian(HumanLanguage)
可能有意义。
编辑以解决问题3:在解释器中,您可以看到为什么打印Ring(HumanLanguage)
仅打印“超级”。完成Ring(Algebra)
:
super(B, self).__class__.__name__
调用z = B()
只会让您获得此特殊proxy object。代理对象是实例可以如何调用“向上”(技术上,“mro”向下);按照Python2文档中的链接。