再探Python类属性与实例属性,类方法与实例方法,LEGB作用域及名字查找顺序,

Python类中的名字查找有好几个点,常见俊龙金马的有关文章

class MyClass:
    cls_attr=0
    cls_attrB=0
    def __init__(self,val1):
        self.attr=val1
        #cls_attr+=1 #UnboundLocalError: local variable 'cls_attr' 
        #referenced before assignment
        '''1、实例方法内不可直接访问类属性,既便访问实例属性
        都要用self.attr,要访问类属性应该也用self.cls_attr
        ,按照实例属性的查找顺序,在实例属性中没找到时到
        类属性中查找,但修改类属性时实际上是将修改后的值
        存放到增加的与类属性同名的实例属性中,从而屏蔽保护
        了类属性。或者直接"类对象.类属性",这样就会直接
        修改到类属性了。
        2、函数与类都会生成作用域,除了内嵌作用域Builtins
        与全局作用域Global,也只有函数与类会生成嵌套作用域
        与局部作用域Enclosed与Local,形成LEGB的作用域查找
        顺序,但类定义中的方法不可以看作是函数,如果方法
        可以看作函数,那此处直接按名访问"嵌套作用域"的类
        属性就是可以的,但实际上不是,因为既便是类方法也
        不能直接按名访问类属性,而是使用类对象引用cls访问
        类属性,使用类对象的属性查找规则
        '''
        self.cls_attr+=1
        '''3、通过实例引用类属性的方式,"self.cls_attr"
        实例一旦修改类属性,会立即为实例增加一个与类属性
        同名的实例属性保存修改后的值,而不会影响类属性,
        类属性本就是给类、全体实例访问的,这样做到实例
        属性屏蔽从而保护类属性
        '''
        MyClass.cls_attrB+=1
        '''4、直接在实例方法内使用"类对象.类属性"的方式,
        修改类属性是直接影响的类属性
        '''
    def get_cls_attr(self):
        return self.cls_attr
        '''实例当然能访问类属性,实例属性的查找顺序有好几个点'''
    @classmethod
    def get_cls_attrc(cls):
        return cls.cls_attr
    @classmethod
    def set_cls_attr(cls,val):
        cls.cls_attr=val 
        '''5、或者在类方法内使用"类对象引用类属性"修改类属性本身
        '''

obj=MyClass(1) #类属性cls_attr仍然是0,增加实例属性cls_attr=1
obj2=MyClass(1) #类属性cls_attr仍然是0,增加实例属性cls_attr=1
print(obj.get_cls_attr()) #1
print(obj2.get_cls_attr()) #1
print(MyClass.get_cls_attrc()) #0,被obj.cls_attr与obj2.cls_attr屏蔽保护了
print(MyClass.cls_attrB) #2 使用"类对象.类属性"修改类属性将影响本身
MyClass.set_cls_attr(9) 
print(MyClass.get_cls_attrc()) #9

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值