python中类的命名空间和面向对象的诸多问题
2017-07-11 17:53
477 查看
原文地址:http://blog.csdn.net/maopaopao2087/article/details/41115963
python中的作用域
以前一直对C++不行,为什么呢 ? 原来最终的原因是没有全局观,就是没有去看作用域的问题,理解命名空间好重要啊。
python中,或者说面向对象编程中,命名空间的概念很重要,也就是各个东西的作用域很重要。python运行坏境有内置的作用域,模块有模块的作用域,函数有函数的作用域,类有类的作用域,类的实例也就是对象有对象的作用域。
# python中: ‘命名空间’ 就是 ‘字典’
下面说一下类的命名空间和对象的命名空间:
以前我真的没有完全理解面向对象的核心意思。类是有自己的命名空间的,在python中类的定义实际上也是一个可执行的代码块。类的对象,也是有自己的命名空间的,比如讲
恩,这个例子非常的好,类A是有自己的命名空间的(字典),对象a也是有自己的命名空间的。这里有屏蔽的作用,就是跟局部变量和全局变量一样,对象自己有的时候,就不去类里面去找了,就是把类里面的变量给屏蔽掉了,对象里面没有的话要到类里面去找。
这里,类A中的count变量是属于类的命名空间中的,对象a的命名空间中没有,当a.count时候,首先会在对象的命名空间中找count,然后发现自己的命名空间(字典)中并没有count,然后才到类中去找。a.count1 = ‘hello’这句话的意思是创建一个对象hello,在对象a的命名空间中,创建一个变量来绑定这个‘hello’,count1就属于a对象的命名空间了,不属于类。
再解释一下,为什么命名空间中的方法为什么都用self,作为第一个参数?
因为对象调用方法,比如讲a.init() 这里,a对象首先会在本命名空间中找方法init的,发现没有,才到类的命名空间中去找的,好,现在调用了类中的方法init(),如果执行:A.count += 1,意思是把类空间中的count给加1。而如果执行:self.count += 1 ,那是self.count = self.count + 1,根据赋值的变量是local的和self.count=self.count+1,表明是在对象a的命名空间中创建的变量count,而跟类没关系了。 这点很有意思。也算真正理解了面向对象编
4000
程了吧。靠,花了好长时间。
还有一句话:
我们编写的.py文件,可以不用.py结尾的,随便是什么啦,只要是文件就行。 比如讲os,math这些模块就没有以.py结尾。
我们编写的.py文件,也是一个模块!
模块里面定义的变量、导入的模块名、定义的函数名、定义的类名,还有类的对象名都是global的。用globals()函数可以查看模块命名空间中变量。虽然类的对象也是global的,但是如果对象中有的变量的,查找不到的,是到类中去找,找不到就有异常,不到其它地方找。
函数中定义的变量那都是local的,函数中用locals()函数可以查看本函数命名空间中的变量。
类和对象,要查看自己的命名空间,用A.dict 和 a.dict 这个字典变量就可以。而模块中用globals(),函数中用locals()
上面的这些东西很重要,也算是理解面向对象的精髓,暂时可以解决我关于面向对象的所有的疑问。
python中的作用域
以前一直对C++不行,为什么呢 ? 原来最终的原因是没有全局观,就是没有去看作用域的问题,理解命名空间好重要啊。
python中,或者说面向对象编程中,命名空间的概念很重要,也就是各个东西的作用域很重要。python运行坏境有内置的作用域,模块有模块的作用域,函数有函数的作用域,类有类的作用域,类的实例也就是对象有对象的作用域。
# python中: ‘命名空间’ 就是 ‘字典’
下面说一下类的命名空间和对象的命名空间:
以前我真的没有完全理解面向对象的核心意思。类是有自己的命名空间的,在python中类的定义实际上也是一个可执行的代码块。类的对象,也是有自己的命名空间的,比如讲
>>>class A: count = 0 def init(self): A.count += 1 # 这里是A.count而不是self.count,类的对象调用此函数时候,操纵的是类命名空间中的count,而对象命名空间中并没有count这个变量。 >>> a = A() >>> a.init() >>> a.count 1 >>> a.count1 = ‘hello’ >>> a.count1 hello >>> >>>a.__dict__ {‘count1’:’hello’}
恩,这个例子非常的好,类A是有自己的命名空间的(字典),对象a也是有自己的命名空间的。这里有屏蔽的作用,就是跟局部变量和全局变量一样,对象自己有的时候,就不去类里面去找了,就是把类里面的变量给屏蔽掉了,对象里面没有的话要到类里面去找。
这里,类A中的count变量是属于类的命名空间中的,对象a的命名空间中没有,当a.count时候,首先会在对象的命名空间中找count,然后发现自己的命名空间(字典)中并没有count,然后才到类中去找。a.count1 = ‘hello’这句话的意思是创建一个对象hello,在对象a的命名空间中,创建一个变量来绑定这个‘hello’,count1就属于a对象的命名空间了,不属于类。
再解释一下,为什么命名空间中的方法为什么都用self,作为第一个参数?
因为对象调用方法,比如讲a.init() 这里,a对象首先会在本命名空间中找方法init的,发现没有,才到类的命名空间中去找的,好,现在调用了类中的方法init(),如果执行:A.count += 1,意思是把类空间中的count给加1。而如果执行:self.count += 1 ,那是self.count = self.count + 1,根据赋值的变量是local的和self.count=self.count+1,表明是在对象a的命名空间中创建的变量count,而跟类没关系了。 这点很有意思。也算真正理解了面向对象编
4000
程了吧。靠,花了好长时间。
还有一句话:
我们编写的.py文件,可以不用.py结尾的,随便是什么啦,只要是文件就行。 比如讲os,math这些模块就没有以.py结尾。
我们编写的.py文件,也是一个模块!
模块里面定义的变量、导入的模块名、定义的函数名、定义的类名,还有类的对象名都是global的。用globals()函数可以查看模块命名空间中变量。虽然类的对象也是global的,但是如果对象中有的变量的,查找不到的,是到类中去找,找不到就有异常,不到其它地方找。
函数中定义的变量那都是local的,函数中用locals()函数可以查看本函数命名空间中的变量。
类和对象,要查看自己的命名空间,用A.dict 和 a.dict 这个字典变量就可以。而模块中用globals(),函数中用locals()
上面的这些东西很重要,也算是理解面向对象的精髓,暂时可以解决我关于面向对象的所有的疑问。
相关文章推荐
- python __name__属性带来命名空间问题
- Javascript面向对象之命名空间问题
- python面向对象之类的命名空间与组合
- Qt中扩展插件 命名空间的问题
- 诡异的命名空间问题
- 解决vs2005,ASP.NET2.0自定义命名空间问题!
- 命名空间问题using name space
- 找不到类型或命名空间名称“Excel”的问题
- .Net中命名空间的问题(区分大小写)
- 遭遇InfoPath 命名空间问题,ns0 or ns1
- 命名空间的问题
- .NET : 再谈谈XML中的命名空间问题
- .net 2003中类名和命名空间重名时会出现引用问题
- .NET : 再谈谈XML中的命名空间问题
- 【Notes】命名空间的问题
- 诡异的命名空间问题
- 解决vs2005,ASP.NET2.0自定义命名空间问题!(转)
- 解决vs2005,ASP.NET2.0自定义命名空间问题!
- VS解决方案中引用子工程命名空间中的函数无法识别的问题
- Memcached FAQ(4) 选项、Item过期和命名空间方面的问题