Python中的类属性和实例属性以及静态方法和类方法
2014-02-28 15:20
686 查看
可以在Python的类定义中直接添加静态变量,如下例中的foo。此属性属于类C,可以直接通过C.foo访问,而无需实例化它。而实例属性则只存在于对象的实例中,这也就意味着,每一个不同的实例都有只属于自己的实例属性。
1 class C:
2 def __init__(self):
3 pass
4 foo = 'foo'
5
6 c = C()
当我们试图通过一个实例访问某个属性的时候,解释器会首先尝试在实例的命名空间里寻找,如果找不到就会去类属性里找。因此,便会出现下面的情况:
>>> C.foo
'foo'
>>> c.foo
'foo'
>>> C.foo = 'bar'
>>> C.foo
'bar'
>>> c.foo
'bar'
>>> c.foo = 'instantiation'
>>> c.foo
'instantiation'
>>> C.foo
'bar'
当我们实例化C类并将此实例赋值给c时,通过类C和实例c都可以访问到foo属性,实际上这时候访问的是同一个“类属性”(此属性不存在于实例c的命名空间中)。这一点从下面,我们通过类C改变foo的值后,通过实例c访问foo的值也变了,可以看得出来。而当我们试图通过实例c给foo赋值的时候,解释器会把c.foo = 'instantiation'
这条命令理解为“给实例c的foo属性赋值”,而当他发现实例c没有foo属性的时候,便会自动的给实例c创建一个。这个时候再通过实例c去访问类C的类属性foo就是行不通的了。
通过上面的例子可以看到,类属性的本体是属于类自身的,而实例仅在没有自己的同名实例属性时才可以访问到他。这种特质的一个应用方式就是标记类自身的某些属性,比如版本信息。
P.S.类定义的方法全都是类属性,在实例被创建之前这些方法都不能被调用,因为他们还没有被绑定到特定的实例上。或者也可以简单的理解为,缺少可以传递给类方法的self参数因而调用失败。(arguments 0 given 1 required)除非:使用staticmethod()或classmethod()内建函数将类定义的某个方法“标记(tag),强制类型转换(cast)或者转换(convert)”为静态方法或者类方法。例如如下定义C类:
class C:
def __init__(self):
pass
def foo():
print("calling static method foo().")
foo = staticmethod(foo)
def bar(cls):
print("calling class method bar().")
print("bar() is part of class:",cls.__name__)
bar = classmethod(bar)
当调用foo()和bar()方法时,就不用再实例化C了。注意类方法bar()在定义时传入的默认参数cls,这与self类似:
>>> C.foo()
calling static method foo().
>>> C.bar()
calling class method bar().
bar() is part of class: C
(黑色的背景好看吗?话说为啥就找不到个转IDLE默认主题高亮代码的地方呢,其实都是新浪的错吧...最后这段是天依蓝哦)关于Python的类定义方法时为啥必须显式传递一个self参数的问题,也许就是为了“显式”地区分实例方法和非实例方法,这种一目了然也正是Python一贯的风格。
1 class C:
2 def __init__(self):
3 pass
4 foo = 'foo'
5
6 c = C()
当我们试图通过一个实例访问某个属性的时候,解释器会首先尝试在实例的命名空间里寻找,如果找不到就会去类属性里找。因此,便会出现下面的情况:
>>> C.foo
'foo'
>>> c.foo
'foo'
>>> C.foo = 'bar'
>>> C.foo
'bar'
>>> c.foo
'bar'
>>> c.foo = 'instantiation'
>>> c.foo
'instantiation'
>>> C.foo
'bar'
当我们实例化C类并将此实例赋值给c时,通过类C和实例c都可以访问到foo属性,实际上这时候访问的是同一个“类属性”(此属性不存在于实例c的命名空间中)。这一点从下面,我们通过类C改变foo的值后,通过实例c访问foo的值也变了,可以看得出来。而当我们试图通过实例c给foo赋值的时候,解释器会把c.foo = 'instantiation'
这条命令理解为“给实例c的foo属性赋值”,而当他发现实例c没有foo属性的时候,便会自动的给实例c创建一个。这个时候再通过实例c去访问类C的类属性foo就是行不通的了。
通过上面的例子可以看到,类属性的本体是属于类自身的,而实例仅在没有自己的同名实例属性时才可以访问到他。这种特质的一个应用方式就是标记类自身的某些属性,比如版本信息。
P.S.类定义的方法全都是类属性,在实例被创建之前这些方法都不能被调用,因为他们还没有被绑定到特定的实例上。或者也可以简单的理解为,缺少可以传递给类方法的self参数因而调用失败。(arguments 0 given 1 required)除非:使用staticmethod()或classmethod()内建函数将类定义的某个方法“标记(tag),强制类型转换(cast)或者转换(convert)”为静态方法或者类方法。例如如下定义C类:
class C:
def __init__(self):
pass
def foo():
print("calling static method foo().")
foo = staticmethod(foo)
def bar(cls):
print("calling class method bar().")
print("bar() is part of class:",cls.__name__)
bar = classmethod(bar)
当调用foo()和bar()方法时,就不用再实例化C了。注意类方法bar()在定义时传入的默认参数cls,这与self类似:
>>> C.foo()
calling static method foo().
>>> C.bar()
calling class method bar().
bar() is part of class: C
(黑色的背景好看吗?话说为啥就找不到个转IDLE默认主题高亮代码的地方呢,其实都是新浪的错吧...最后这段是天依蓝哦)关于Python的类定义方法时为啥必须显式传递一个self参数的问题,也许就是为了“显式”地区分实例方法和非实例方法,这种一目了然也正是Python一贯的风格。
相关文章推荐
- Python中的类属性和实例属性以及静态方法和类方法
- Python中的类属性、实例属性与类方法、静态方法
- python 类属性 实例属性 类方法 实例方法 静态方法(转载)
- Python:类属性,实例属性,私有属性与静态方法,类方法,实例方法 属性分为实例属性与类属性 方法分为普通方法,类方法,静态方法 一:属性: 尽量把需要用户传入的属性作为实例属性,而
- Struts2中使用OGNL表达式语言访问静态方法和静态属性以及我遇到的问题和解决方法
- Python使用MySQL数据库的方法以及一个实例
- Python 成员方法,类方法以及静态方法
- 利用python打印出菱形、三角形以及矩形的方法实例
- Python学习:给类的实例绑定属性和方法
- python语言是动态语言、给类添加属性、方法、静态方法和类方法、__slots__()、python中的生成器、yield的用法
- 简单理解Python中的类对象、实例对象、属性、方法
- python的类变量与实例变量以及__dict__属性
- Python复数属性和方法操作实例
- python学习之初始化实例、类属性、方法
- 【Python_OpenCv】笔记4:python,OpenCv中对图片像素的操作以及图片基本属性的获取方法
- python语言是动态语言、给类添加属性、方法、静态方法和类方法、__slots__()、python中的生成器、yield的用法
- python 随机数使用方法,推导以及字符串,双色球小程序实例
- python学习笔记-实例方法、类方法、静态方法、属性方法
- Python:类属性,实例属性,私有属性与静态方法,类方法,实例方法
- python进阶学习笔记(四)——python中访问限制、创建类属性、定义实例方法、定义类方法、类的继承