您的位置:首页 > 编程语言 > Python开发

Python中的类属性和实例属性以及静态方法和类方法

2015-08-06 19:20 841 查看
可以在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

关于Python的类定义方法时为啥必须显式传递一个self参数的问题,也许就是为了“显式”地区分实例方法和非实例方法,这种一目了然也正是Python一贯的风格。

转载自:http://blog.sina.com.cn/s/blog_4a38d5fd0101rx8v.html

-------------------------------
class C:
def __init__(self):
pass
   def foo():
print("calling static method foo().")
foo = staticmethod(foo)

def bar(a1,b):
print("calling class method bar().")
print("bar() is part of class:",a1.__name__)
bar = classmethod(bar)

C.foo()
C.bar()

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

输入结果:

C.bar()

TypeError: bar() takes exactly 2 arguments (1 given)

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

在PYTHON中,两种方法的主要区别在于参数。实例方法隐含的参数为类实例self,而类方法隐含的参数为类本身cls。

静态方法无隐含参数,主要为了类实例也可以直接调用静态方法。

  所以逻辑上类方法应当只被类调用,实例方法实例调用,静态方法两者都能调用。主要区别在于参数传递上的区别,实例方法悄悄传递的是self引用作为参数,而类方法悄悄传递的是cls引用作为参数。

  Python实现了一定的灵活性使得类方法和静态方法,都能够被实例和类二者调用
==========================================================================================================

@staticmethod A way to write a method inside a class without reference to the object it is being called on. So no need to pass implicit argument like self or cls. It is written exactly the same how written
outside the class, but it is not of no use in python because if you need to encapsulate a method inside a class since this method needs to be the part of that class @staticmethod is comes handy in that case.

@classmethod It is important when you want to write a factory method and by this custom attribute(s) can be attached in a class. This attribute(s) can be overridden in the inherited class.

A comparison between these two methods can be as below



内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: