python 属性访问疑问

2016-01-07 16:27:09 +08:00
 mink
class B(object):
    def __init__(self):
        self.name ='mink'

class A(B):
    name = 'kk'

a = A()

# pirnt 'mink'
print a.name

我访问 a.name 会访问 B 的实例属性,而不是 A 的类属性,是不是我在创建实例 a 的时候默认用 B 的构造方法创建的啊?

3190 次点击
所在节点    Python
15 条回复
Kilerd
2016-01-07 16:35:16 +08:00
建议看看 类的继承和派生 相对应内容
lovedboy
2016-01-07 16:41:11 +08:00
class B(object):

def __new__(self):
print "new:",self.name
return super(B,self).__new__(self)
def __init__(self):
print 'init:', self.name
self.name ='mink'
pass

class A(B):
name = 'kk'

a = A()

# pirnt 'mink'
print a.name
ljdawn
2016-01-07 16:57:39 +08:00
实例的属性存储在实例的__dict__中,类属性存储在类的__dict__中.查找时先查找实例的__dict__,然后才是类的__dict__
knightdf
2016-01-07 16:59:32 +08:00
__new__才是实例构造器,__init__是实例初始化的, new 后自动调用 init ,然后你就懂了
hzm0318hzm
2016-01-07 17:01:11 +08:00
A 也需要__init__函数,在里面赋值就行了
cizixs
2016-01-07 17:05:25 +08:00
类 A 可粗略写成这样:

class A(object):
name = 'kk'

def __init__(self):
self.name ='mink'

包括了实例属性和类属性, python 访问的时候会先访问实例属性,然后是类属性,你可以用 a.__class__.ame 来访问类属性。
lixiaohan
2016-01-07 17:12:43 +08:00
对于 A 来说 name 是它的类变量 而不是实例变量,其实它本身没有实例变量, 所以就用 B 的 就是这个结果了。
playniuniu
2016-01-07 17:15:27 +08:00
那是必须的,和继承没关系,想要打出 kk ,需要 print( A.name) 这才是类的值, a.name 已经是类的一个实例了
mink
2016-01-07 17:35:41 +08:00
感谢你们的回答,我想问的是这样的。当 A 的实例 a 创建以后, a 的__dict__的空的,但是我在通过 A 继承 B 并且 B 中设置__init__。 实例 a 的__dict__里有了 name 这个属性,但是她是来自 B 的__init__。


```python
class B(object):

def __new__(cls):
print 'new:', cls.name
# A
print cls.__name__
return super(B, cls).__new__(cls)

def __init__(self):
print 'init:', self.name
self.name = 'mink'

class A(B):
name = 'kk'

a = A()

print a.name
```
这里我打印了一下 cls.__name__ 竟然是 A ,  cls 参数不是当前类么,有点费解
tonghuashuai
2016-01-07 17:50:54 +08:00
这样就好了

class B(object):
def __init__(self):
self.name ='mink'

class A(B):
# A 也要有 init 方法
def __init__(self):
self.name ='kk'

a = A()

# pirnt 'kk'
print a.name
billlee
2016-01-07 21:11:32 +08:00
就是实例的属性会覆盖掉类属性嘛
vixvix
2016-01-07 22:27:20 +08:00
>>> class B(object):
... def __init__(self):
... self.name ='mink'
...
>>> class A(B):
... name = 'kk'
...
>>> a = A()
>>>
>>> # pirnt 'mink'
... print a.name
mink
>>> print A.name
kk
>>>
rxkh
2016-01-08 10:30:18 +08:00
print A.name
mink
2016-01-08 10:51:10 +08:00
其实我想知道实例创建时初始化过程,如果

class B(object):
def __init__(self):
self.name = 'mink'

class A(object):
name = 'kk'

a = A()

# pritn {'name': 'mink'}
# print 'mink'
print a.__dict__
print a.name

我现在确定的是当实例 a 被创建出来时,如果 A 类没有初始化函数__init__就会在父类找。如果找到就执行父类的__init__,如果找不到几继续往上找。以下是测试的

class C(object):
def __init__(self):
print 'in c'
self.name = 'c mink'

class B(object):
def __init__(self):
print 'in b'
self.age = 3

class A(B, C):
name = 'kk'

a = A()

# print {'age': 3}
# pirnt 'kk'
print a.__dict__
print a.name

因为他在 b 中找到了__init__就不往上继续查了,这样 a.name 就会返回类的 name 也就是 kk

class C(object):
def __init__(self):
print 'in c'
self.name = 'c mink'

class B(object):
age = 3

class A(B, C):
name = 'kk'

a = A()

# print {'name': 'c mink'}
# pirnt 'c mink'
print a.__dict__
print a.name
mink
2016-01-08 10:53:07 +08:00
这样就找到了,所以能找到 C 中的 'c mink'。 感谢你们的回答

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/249070

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX