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

[Python]面向对象编程---类、实例、方法的对比(4)

2017-04-26 11:14 106 查看
一、类属性 vs 实例属性

1、访问类属性

>>> class C(object): # 定义类
version = 1.2 # 静态成员

(1) 当用实例来访问类属性时,Python会先在实例中搜索名字version,然后是类,再就是继承树中的基类。
(2) 通过类才能更新它的值
>>> c = C()                 # 实例化
>>> C.version               # 通过类来访问
1.2
>>> c.version               # 通过实例来访问
1.2
>>> C.version += 0.1        # 通过类来更新(只能这样)
>>> C.version               # 类访问
1.3
>>> c.version               # 实例访问它,其值已被改变
1.3


2、通过实例访问类的属性

任何对实例属性的赋值都会创建一个实例属性(如果不存在的话),并且对其赋值。

如果类属性中存在同名的属性,会产生副作用

>>> c.version += 0.2       # 尝试更新类属性  等价于 c.version = C.version + 0.2
>>> c.version              # 只是创建了一个新的实例属性
1.5
>>> C.version              # 没有更新类属性,只是创建了一个新的实例属性
1.3
>>> del c.version          # 删除实例属性
>>> c.version              # 又可以访问到类属性
1.3
>>> C.version
1.3
3、在类属性可变的情况下,通过实例可以更新类属性
>>> class Foo(object):
... x = {2003: 'yes'} # 字典类型,可以修改
>>> foo = Foo()             # 实例化
>>> foo.x
{2003: 'yes'}
>>> foo.x[2004] = 'no'      # 通过实例修改类属性,生效
>>> foo.x
{2003: 'yes', 2004: 'no'}
>>> Foo.x                   # 修改生效
{2003: 'yes', 2004: 'no'}
>>> del foo.x               # 没有遮蔽所以不能删除掉
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: x
二、绑定和方法调用
1、方法

(1) 方法仅仅是类内部定义的函数(是类属性,不是实例属性)

(2) 方法只有在其所属的类拥有实例时,才能被调用

(3) 任何一个方法定义中的第一个参数都是变量self,它表示调用此方法的实例对象。

2、调用绑定方法

MyClass类和实例mc,想要调用MyClass中的方法foo,只需调用mc.foo()即可。

3、调用非绑定方法

当没有实例并且需要调用一个非绑定方法时,必须传递self参数

def __init__(self, nm, ph, id, em):
AddrBookEntry.__init__(self, nm, ph) # 通过父类名来调用
self.empid = id
self.email = em三、静态方法 vs 类成员方法
静态方法可以被类或实例访问不能访问类变量,不能访问实例变量。

类成员方法可以被类或实例访问,可以访问类变量,不能访问实例变量。

class MyClass(object):
val1 = 'abcd' # 类属性
def __init__(self):
self.val2 = 'a1b2c3' # 实例属性

@staticmethod # 使用装饰器定义静态方法
def staticMd():
print("static method, can't access val1 and val2")

@classmethod # 使用装饰器定义类成员方法
def classMd(cls):
print("class method, class: %s, val1 = %s, can't access val1" % (str(cls), cls.val1))
>>> mc = MyClass()        # 实例化

>>> mc.staticMd()         # 通过实例访问静态方法
static method, can't access val1 and val2
>>> MyClass.staticMd()    # 通过类访问静态方法
static method, can't access val1 and val2

>>> mc.classMd()          # 通过实例访问类成员方法
class method, class: <class 'MyData.MyClass'>, val1 = abcd, can't access val1
>>> MyClass.classMd()     # 通过类访问类成员方法
class method, class: <class 'MyData.MyClass'>, val1 = abcd, can't access val1
>>> mc.val1               # 实例访问类属性
'abcd'
>>> MyClass.val1          # 类访问类属性
'abcd'

>>> mc.val2               # 实例访问实例
a67c
属性
'a1b2c3'
>>> MyClass.val2          # 类无法访问实例属性
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: type object 'MyClass' has no attribute 'val2'
>>> mc.val1 = "haha"     # 创建了一个实例属性 val1
>>> mc.val1              # 访问实例属性 val1
'haha'
>>> MyClass.val1         # 此时类属性val1并没有改变
'abcd'

>>> MyClass.val1 = "a1b1c1"  # 通过类更新类属性
>>> MyClass.val1         # 类属性已经更新
'a1b1c1'
>>> mc.val1              # 实例属性val1没有改变
'haha'
>>> del mc.val1          # 删除实例属性val1
>>> mc.val1              # 此时可以通过实例访问类属性
'a1b1c1'
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: