首页 > 代码库 > class 类(2)

class 类(2)

类属性和实例属性

一个类实例化后,实例是一个对象,有属性。同样,类也是一个对象,它也有属性。

>>> class A(object):...     x = 7...
>>> A.x7

在类A中,变量x所引用的数据,能够直接通过类来调用。或者说x是类A的属性,这种属性有一个名称,曰“类属性”。类属性仅限于此——类中的变量。它也有其他的名字,如静态数据。

>>> foo = A()>>> foo.x7

实例化,通过实例也可以得到这个属性,这个属性叫做“实例属性”。对于同一属性,可以用类来访问(类属性),在一般情况下,也可以通过实例来访问同样的属性。

当类中变量引用的是可变对象是,类属性和实例属性都能直接修改这个对象,从而影响另一方的值。

数据流转

技术分享

创建实例girl = Person(‘canglaoshi‘),注意观察图上的箭头方向。girl这个实例和Person类中的self对应,这正是应了上节所概括的“实例变量与self对应,实例变量主外,self主内”的概括。"canglaoshi"是一个具体的数据,通过初始化函数中的name参数,传给self.name,前面已经讲过,self也是一个实例,可以为它设置属性,self.name就是一个属性,经过初始化函数,这个属性的值由参数name传入,现在就是"canglaoshi"。

在类Person的其它方法中,都是以self为第一个或者唯一一个参数。注意,在python中,这个参数要显明写上,在类内部是不能省略的。这就表示所有方法都承接self实例对象,它的属性也被带到每个方法之中。例如在方法里面使用self.name即是调用前面已经确定的实例属性数据。当然,在方法中,还可以继续为实例self增加属性,比如self.breast。这样,通过self实例,就实现了数据在类内部的流转。

如果要把数据从类里面传到外面,可以通过return语句实现。如上例子中所示的getName方法。 

 

因为实例名称(girl)和self是对应关系,实际上,在类里面也可以用girl代替self。例如,做如下修改:

#!/usr/bin/env python# coding=utf-8__metaclass__ = typeclass Person:    def __init__(self, name):        self.name = name    def getName(self):        #return self.name        return girl.name    #修改成这个样子,但是在编程实践中不要这么做。girl = Person(canglaoshi)name = girl.getName()print name

 

命名空间

命名空间是从所定义的命名到对象的映射集合。

不同的命名空间,可以同时存在,当彼此相互独立互不干扰。

 

命名空间因为对象的不同,也有所区别,可以分为如下几种:

  • 内置命名空间(Built-in Namespaces):Python运行起来,它们就存在了。内置函数的命名空间都属于内置命名空间,所以,我们可以在任何程序中直接运行它们,比如前面的id(),不需要做什么操作,拿过来就直接使用了。
  • 全局命名空间(Module:Global Namespaces):每个模块创建它自己所拥有的全局命名空间,不同模块的全局命名空间彼此独立,不同模块中相同名称的命名空间,也会因为模块的不同而不相互干扰。
  • 本地命名空间(Function&Class: Local Namespaces):模块中有函数或者类,每个函数或者类所定义的命名空间就是本地命名空间。如果函数返回了结果或者抛出异常,则本地命名空间也结束了。

“类命名空间”——定义类时,所有位于class语句中的代码都在某个命名空间中执行,即类命名空间。

作用域

 

作用域是指 Python 程序可以直接访问到的命名空间。“直接访问”在这里意味着访问命名空间中的命名时无需加入附加的修饰符。

def outer_foo():    b = 20    def inner_foo():        c = 30a = 10

假如我现在位于inner_foo()函数内,那么c对我来讲就在本地作用域,而b和a就不是。如果我在inner_foo()内再做:b=50,这其实是在本地命名空间内新创建了对象,和上一层中的b=20毫不相干。

如果要将某个变量在任何地方都使用,且能够关联,那么在函数内就使用global 声明,其实就是曾经讲过的全局变量。

 

class 类(2)