zoukankan      html  css  js  c++  java
  • 我的Python学习笔记(三):私有变量

    一、私有变量的定义

    在Python中,有以下几种方式来定义变量:

    • xx:公有变量
    • _xx:单前置下划线,私有化属性或方法,类对象和子类可以访问,from somemodule import *禁止导入
    • __xx:双前置下划线,私有化属性或方法,无法在外部直接访问(名字重整所以访问不到)
    • __xx__:双前后下划线,系统定义名字(不要自己发明这样的名字)
    • xx_:单后置下划线,用于避免与Python关键词的冲突

    如以下例子所示,我在test类中定义了num,_num 和 __num三个属性,并创建了test的类对象t,对这三个属性进行访问,__num不能被访问到

    class test(object):
        def __init__(self):
            self.num = 10
            self._num = 20
            self.__num = 30
    
    t = test()
    print(t.num)    # 10
    print(t._num)   # 20
    # print(t.__num)  # AttributeError: 'test' object has no attribute '__num'

    可以使用命令dir查看t中的属性和方法,__num的名字已经被重整为“_test__num”了,可以使用t._test__num对__num进行访问

    注:虽然私有变量可以通过_类名__变量名来访问,但强烈建议不要这样做

    二、使用不同方法导入模块,模块中私有变量的使用区别

    在使用不同方法导入模块后,是否能使用模块中的私有属性和方法,有以下两种情况

    • 在使用 from somemodule import * 导入模块的情况下,不能导入或使用私有属性和方法
    • 在使用 import somemodule 导入模块的情况下,能导入并使用私有属性和方法

    首先我们先创建一个test.py文件,将下面代码复制进去:

    num = 10
    _num = 20
    __num = 30
    
    def test():
        print("--test--")
    
    def _test2():
        print("--test2--")
    
    def __test3():
        print("---test3--")
    • 使用 from somemodule import * 进行导入,不能导入私有变量,结果如下:
    In [1]: from test import *
    
    In [2]: num
    Out[2]: 10
    
    In [3]: _num
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-3-6dd7111d6a95> in <module>()
    ----> 1 _num
    
    NameError: name '_num' is not defined
    
    In [4]: __num
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-4-f0ba2c4a214a> in <module>()
    ----> 1 __num
    
    NameError: name '__num' is not defined
    
    In [5]: test()
    --test--
    
    In [6]: _test2()
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-6-d29889233d08> in <module>()
    ----> 1 _test2()
    
    NameError: name '_test2' is not defined
    
    In [7]: __test3()
    ---------------------------------------------------------------------------
    NameError                                 Traceback (most recent call last)
    <ipython-input-7-17e592a156f3> in <module>()
    ----> 1 __test3()
    
    NameError: name '__test3' is not defined
    • 使用 import somemodule 进行导入,能导入私有变量,结果如下:
    In [8]: import test
    
    In [9]: test.num
    Out[9]: 10
    
    In [10]: test._num
    Out[10]: 20
    
    In [11]: test.__num
    Out[11]: 30
    
    In [12]: test.test()
    --test--
    
    In [13]: test._test2()
    --test2--
    
    In [14]: test.__test3()
    ---test3--

    三、对类中的私有属性进行操作的方法

    如果你想对类中的私有属性进行操作时,有以下三种方法:

    1、getter和setter:

    添加getter和setter方法,类对象通过调用这两种方法来对私有属性进行操作

    class test(object):
        def __init__(self):
            self.__num = 10
            
        def getNum(self):
            return self.__num
    
        def setNum(self, value):
            self.__num = value
    
    t = test()
    print(t.getNum())   # 10
    t.setNum(20)
    print(t.getNum())   # 20

      2、property方法

    class test(object):
        def __init__(self):
            self.__num = 10
    
        def getNum(self):
            return self.__num
        
        def setNum(self, value):
            self.__num = value
    
        num = property(getNum,setNum)
    
    t = test()
    print(t.num)   # 10
    t.num = 20
    print(t.num)   # 20

    关于property方法,我们来看下官方文档:

    由文档可得:

    • property方法包含四个参数,分别为fget,fset,fdel,doc,分别对应getter方法,setter方法,deleter方法和方法说明
    • property()方法返回一个property属性,如果c是C的实例,那么c.x会调用getter方法,c.x = value会调用setter方法,而del c.x会调用deleter方法

      

      3、@property

    class test(object):
        def __init__(self):
            self.__num = 10
    
        @property
        def num(self):
            return self.__num
    
        @num.setter
        def num(self, value):
            self.__num = value
    
    t = test()
    print(t.num)   # 10
    t.num = 20
    print(t.num)   # 20

    关于@property,官方文档如下:

    根据文档可得:

    • 我们可以把property()方法当成一个装饰器来使用,使用@property对方法进行装饰
    • 装饰器@property把方法x()转换成了与方法名同名的getter方法,"I'm the 'x' property."是property的doc参数
    • 调用方法和property()方法一样
  • 相关阅读:
    [原]C++ double 小数精度控制
    C++ double 小数精度控制
    从微软小冰看微软运营手段的转型
    Windows下搭建FTP服务器
    C++ 下使用curl 获取ftp文件
    解决MSF更新证书错误
    mimikaz获取明文密码
    metasploit5配置数据库
    Cobalt Strike几种不常见的上线方式
    Powershell
  • 原文地址:https://www.cnblogs.com/semon-code/p/8242062.html
Copyright © 2011-2022 走看看