Python 类中实例变量和类变量还有类内定义的函数,它们之间作用域是怎样的,变量之间的关系是怎样?

2014-03-02 10:30:31 +08:00
 Matrix24
6441 次点击
所在节点    Python
10 条回复
gaicitadie
2014-03-02 11:05:53 +08:00
跑个题,关注这些偏门的知识点真的很无聊,如同ruby的元编程,php的切面编程。除了面试别人或被人面试的时候拿出来装个逼,平时开发真的用不到这些知识点
binux
2014-03-02 11:45:04 +08:00
实例变量和类变量,哪有什么作用域?你哪次不是self.foo这样访问的?
zorceta
2014-03-02 12:02:17 +08:00
likexian
2014-03-02 12:15:56 +08:00
好多名词,一个也不懂,怎么办
Matrix24
2014-03-02 14:47:22 +08:00
Matrix24
2014-03-02 15:05:58 +08:00
hitsmaxft
2014-03-02 22:38:16 +08:00
实例变量和类变量这些基础的知识还偏门? 某些朋友不能误人子弟啊.

然后, 这些任何一本python书里都有,请仔细看下class相关内容.

http://docs.python.org/3/tutorial/classes.html 官方的说法

http://woodpecker.org.cn/diveintopython/object_oriented_framework/class_attributes.html 一篇中文的, 粗略喵了一眼, 应该没什么硬伤.

我能说的只有这些, 你懂的.
hitsmaxft
2014-03-02 22:40:27 +08:00
@binux 一个实例没创建之间, 哪有实例变量可以访问?

能问这种问题, 相必是基础知识不牢靠的, 问题本身可能就是错的
Hualin
2014-03-03 00:58:12 +08:00
Python 中除了基本类型(int,str,float)这种的,其他 list,dict,object 等作为函数参数都会传其引用(在函数里如果改了,不用 return,除了函数,那个变量里面的内容已经变了),除非明显给出 copy()。而且这些类型有时在用被某些函数用个之后 类型会变成其子类。比如 dict 会变成 local (可以当做 dict 用,但比 dict 更特别一些)。

和 C++ java 等 不同,Python 没有块作用域。在 for loop 和 if block 里定义的变量出去后 还可以访问。

类成员变量,方法 没啥特别,用起来跟其他语言感觉一样,引用都要 self.xxx

我没查文档,以上是个人经验。
yfaming
2014-03-12 17:30:03 +08:00
参考一下 http://docs.python.org/2/reference/datamodel.html#the-standard-type-hierarchy,3.2 节 "The standard type hierarchy" 下 Classes 和 Class instances 两段。

简单说,每个类维护着一个字典叫 __dict__,里面保存类的变量,方法,类方法,静态方法等;每个实例也维护个着字典叫 __dict__,里面保存实例的变量。

通过类来访问属性,如 C.x,首先到类 C 的 __dict__ 里查找,看有没有 'x' 键,若没有则按继承树查找 C 的基类们。

通过实例来访问属性,如 a.x,首先到 a 的 __dict__ 里查找,然后到 a 的类及其基类们的 __dict__ 里查找,方法如上。

没找到,自然抛 AttributeError 异常了。找到了呢,有个 "transform" 的过程,见链接吧。也可暂忽略之,不去管什么 unbound method, bound method, classmethod, staticmethod 什么的。


这里没有作用域什么事,只是有个屏蔽的问题。比如,类的 __dict__ 里有个 x,其实例的 __dict__ 里也有个 x,那么,通过实例访问 x 自然是取实例的 x 而通过类访问 x 就取了类的 x。

要小心的是,类有个 x 而实例没有,执行 a.x = 2 时(a 是实例),则会在实例 a 的 __dict__ 里添加 x,而不是修改类的。

-----------------------

另外,链接那个文档也指出了,其实有很多 hooks 来拦截 C.x 和 a.x 这样的访问的,比如 @property,descriptor 什么的,这些是更“高级”一点的内容了。

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

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

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

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

© 2021 V2EX