zoukankan      html  css  js  c++  java
  • python 类访问控制

    在python类中,有属性和方法,外部代码可以直接通过实例来访问修改.

    如果让内部的属性不被外部访问到,在属性变量前面加上__2个下划线,在python中,实例的变量名如果是由__2个下花钱开头的,就代表这是一个私有变量.只有内部可以访问,外部不许直接通过类或者实例访问.
    代码:
    1 class F:
    2     __name = "xurui"
    3 f = F()
    4 f.__name
    5 F.__name ##报错,AttributeError: type object 'F' has no attribute '__name'
    虽然说外部访问不了一个内部私有属性,但是可以通过类中方法间接的访问到,修改
    类内部方法getname和setname
     1 class F:
     2     __name = "xurui"             
     3     def getName(self):
     4         return self.__name,self
     5     def setName(self,name):
     6         self.__name = name
     7         return self.__name,self
     8 f = F()      #类中self,都是f这实例对象.
     9 res = f.getName()
    10 print(res,f)
    11 result = f.setName("zhangsan")
    12 print(result,f)
    13 结果:
    14 ('xurui', <__main__.F object at 0x0000000000BAA048>) <__main__.F object at 0x0000000000BAA048>
    15 ('zhangsan', <__main__.F object at 0x0000000000BAA048>) <__main__.F object at 0x0000000000BAA048>

    双下划线开头的私有属性,是不是一定不能从外部访问呢?其实不是的

    1 class F:
    2     __name = "xurui"
    3 f = F()
    4 result = f._F__name          ##通过这个方式可以从外部访问...
    5 print(result) 
    python中2个有趣的现象,外部变量遮蔽类中的变量..(来自核心编程)
    从实例中访问类属性必须要谨慎.和通常python变量一样,任何对实例属性的赋值都会创建一个实例属性(如果实例属性不存在的话),并且对其赋值.但是,如果类属性中存在同名的属性,就是产生前面所说的有趣的副作用.python3.x依旧存在.
    下面上代码:
     1 class Foo:
     2     x = 10
     3 f = Foo()
     4 print("原始数据 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))
     5 # print(f.x += 10)
     6 f.x =f.x+10
     7 print("f.x增加10后 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))
     8 del f.x
     9 print("del干掉f.x后 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))
    10 ## 说明,代码创建了一个f.x新的实例属性,它覆盖了对类属性的引用.然而,类属性本身没有受到影响,仍然存在类域中,还可以通过类属性来访问到.给一个与类属性同名的实例属性赋值,我们会有效的遮蔽类属性,一旦我们删除了这个实例属性,类属性又重现天日.
    11 结果:
    12 原始数据 通过实例访问:10,通过类访问:10
    13 f.x增加10后 通过实例访问:20,通过类访问:10
    14 del干掉f.x后 通过实例访问:10,通过类访问:10
     1 class Foo:
     2     x = {"k1" : 10}
     3 f = Foo()
     4 print("原始数据 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))
     5 f.x["k1"] = 20
     6 print("f.x值变20后 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))
     7 del f.x
     8 print("del干掉f.x后 通过实例访问:{},通过类访问:{}".format(f.x,Foo.x))
     9 结果:
    10 Traceback (most recent call last):
    11   File "C:/Users/xurui/PycharmProjects/q1/2017-02-21/lei/lei.py", line 10, in <module>
    12     del f.x
    13 AttributeError: x
    14 原始数据 通过实例访问:{'k1': 10},通过类访问:{'k1': 10}
    15 f.x值变20后 通过实例访问:{'k1': 20},通过类访问:{'k1': 20}
    为什么下面的dict类型的就会del报错呢??
    原因在于:
    python是由c写成的cpython.
    c语言中,并没有字符串这个概念,c中叫做字符数组,存储在内存中,是一块连续的空间,不可修改,任何修改字符数组的行为,都会在不影响原始的字符数组下,创建产生一个新的字符数组..
    而dict就不一样了,它在内存中存储,是一系列非连续的内存空间,可以在原来的基础上修改,所以,第二个例子中del f.x就会报错.
    人生苦短,我用python!
  • 相关阅读:
    linux常用命令
    mysql 开发基础系列20 事务控制和锁定语句(上)
    sql server 性能调优之 资源等待 CXPACKET
    mysql 开发基础系列19 触发器
    mysql 开发基础系列18 存储过程和函数(下)
    mysql 开发基础系列17 存储过程和函数(上)
    sql server 性能调优之 资源等待PAGEIOLATCH
    mysql 开发基础系列16 视图
    mysql 开发基础系列15 索引的设计和使用
    sql server 性能调优之 当前用户请求分析 (1)
  • 原文地址:https://www.cnblogs.com/xu-rui/p/6428558.html
Copyright © 2011-2022 走看看