精华内容
下载资源
问答
  • python类中的私有变量
    2020-12-15 11:52:27

    1.类的私有变量和私有方法

    1)_xx 以单下划线开头的表示的是protected类型的变量。即保护类型只能允许其本身与子类进行访问。若内部变量标示,如:当使用“from Mimport”时,不会将以一个下划线开头的对象引入。

    2)__xx 双下划线的表示的是私有类型的变量。只能允许这个类本身进行访问了,连子类也不可以用于命名一个类属性(类变量),调用时名字被改变(在类FooBar内部,__boo变成_FooBar__boo,如self._FooBar__boo)

    3)__xx__定义的是特列方法。用户控制的命名空间内的变量或是属性,如init , __import__或是file 。只有当文档有说明时使用,不要自己定义这类变量。(就是说这些是python内部定义的变量名)

    4)python默认的成员函数和成员变量都是公开的,没有像其他类似语言的public,private等关键字修饰。但是可以在变量前面加上两个下划线"_",这样的话函数或变量就变成私有的。 **情况就是当变量被标记为私有后,在变量的前端插入类名,在类名前添加一个下划线"_",即形成了_ClassName__变量名.**

    Python内置类属性

    __dict__ : 类的属性(包含一个字典,由类的数据属性组成)

    __doc__: 类的文档字符串

    __module__: 类定义所在的模块(类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__等于 mymod)

    __bases__: 类的所有父类构成元素(包含了一个由所有父类组成的元组)

    例子:

    classStudent(object):

    _name ="huang"

    __sex ="male"

    defhello(self):

    print(self._name)

    print(self.__sex)

    defget_value(self):

    returnself.__sex

    a = Student()

    print(a.hello())

    print(a.get_value())

    结果:

    huang

    male

    None

    male

    更多相关内容
  • 在这里强调说一下私有变量,python默认的成员函数和成员变量都是公开的,没有像其他类似语言的public,private等关键字修饰.但是可以在变量前面加上两个下划线"_",这样的话函数或变量就变成私有的.这是python私有变量...
  • 私有变量表示方法 在变量前加上两个下划线的是私有变量。 class Teacher(): def __init__(self,name,level): self.__name=name self.__level=level #获取老师的等级 def get_level(self): return self.__...
  • python中定义私有变量只需要在变量名或函数名前加上 ”__“两个下划线,那么这个函数或变量就是私有的了。在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__mem...

    默认情况下,Python中的成员函数和成员变量都是公开的(public),在python中没有类似public,private等关键词来修饰成员函数和成员变量。

    在python中定义私有变量只需要在变量名或函数名前加上 ”__“两个下划线,那么这个函数或变量就是私有的了。

    在内部,python使用一种 name mangling 技术,将 __membername替换成 _classname__membername,也就是说,类的内部定义中,

    所有以双下划线开始的名字都被"翻译"成前面加上单下划线和类名的形式。

    例如:为了保证不能在class之外访问私有变量,Python会在类的内部自动的把我们定义的__spam私有变量的名字替换成为

    _classname__spam(注意,classname前面是一个下划线,spam前是两个下划线),因此,用户在外部访问__spam的时候就会

    提示找不到相应的变量。 python中的私有变量和私有方法仍然是可以访问的;访问方法如下:

    私有变量:实例._类名__变量名

    私有方法:实例._类名__方法名()

    其实,Python并没有真正的私有化支持,但可用下划线得到伪私有。 尽量避免定义以下划线开头的变量!

    (1)_xxx "单下划线 " 开始的成员变量叫做保护变量,意思是只有类实例和子类实例能访问到这些变量,

    需通过类提供的接口进行访问;不能用'from module import *'导入

    (2)__xxx 类中的私有变量/方法名 (Python的函数也是对象,所以成员方法称为成员变量也行得通。),

    " 双下划线 " 开始的是私有成员,意思是只有类对象自己能访问,连子类对象也不能访问到这个数据。

    (3)__xxx__ 系统定义名字,前后均有一个“双下划线” 代表python里特殊方法专用的标识,如 __init__()代表类的构造函数。

    下面我们看几个例子:

    【1】

    class A(object):

    def __init__(self):

    self.__data=[] #翻译成 self._A__data=[]

    def add(self,item):

    self.__data.append(item) #翻译成 self._A__data.append(item)

    def printData(self):

    print self.__data #翻译成 self._A__data

    a=A()

    a.add('hello')

    a.add('python')

    a.printData()

    #print a.__data #外界不能访问私有变量 AttributeError: 'A' object has no attribute '__data'

    print a._A__data #通过这种方式,在外面也能够访问“私有”变量;这一点在调试中是比较有用的!

    运行结果是:

    ['hello', 'python']

    ['hello', 'python']

    【2】

    获取实例的所有属性 print a.__dict__

    获取实例的所有属性和方法 print dir(a)

    class A():

    def __init__(self):

    self.__name='python' #私有变量,翻译成 self._A__name='python'

    def __say(self): #私有方法,翻译成 def _A__say(self)

    print self.__name #翻译成 self._A__name

    a=A()

    #print a.__name #访问私有属性,报错!AttributeError: A instance has no attribute '__name'

    print a.__dict__ #查询出实例a的属性的集合

    print a._A__name #这样,就可以访问私有变量了

    #a.__say()#调用私有方法,报错。AttributeError: A instance has no attribute '__say'

    print dir(a)#获取实例的所有属性和方法

    a._A__say() #这样,就可以调用私有方法了

    运行结果:

    {'_A__name': 'python'}

    python

    ['_A__name', '_A__say', '__doc__', '__init__', '__module__']

    python

    从上面看来,python还是非常的灵活,它的oop没有做到真正的不能访问,只是一种约定让大家去遵守,

    比如大家都用self来代表类里的当前对象,其实,我们也可以用其它的,只是大家习惯了用self 。

    【3】小漏洞:派生类和基类取相同的名字就可以使用基类的私有变量

    class A():

    def __init__(self):

    self.__name='python' #翻译成self._A__name='python'

    class B(A):

    def func(self):

    print self.__name #翻译成print self._B__name

    instance=B()

    #instance.func()#报错:AttributeError: B instance has no attribute '_B__name'

    print instance.__dict__

    print instance._A__name

    运行结果:

    {'_A__name': 'python'}

    python

    class A():

    def __init__(self):

    self.__name='python' #翻译成self._A__name='python'

    class A(A): #派生类和基类取相同的名字就可以使用基类的私有变量。

    def func(self):

    print self.__name #翻译成print self._A__name

    instance=A()

    instance.func()

    运行结果:

    python

    展开全文
  • 参考链接: Python中私有变量 我们这里就直奔主题,不做基础铺垫,默认你有一些Python类的基础,大家在看这篇博客的时候,如果基础知识忘了,可以去菜鸟教程 从一个简单的开始 class A(): #定义一个 A a ...

    参考链接: Python中的私有变量

    我们这里就直奔主题,不做基础铺垫,默认你有一些Python类的基础,大家在看这篇博客的时候,如果基础知识忘了,可以去菜鸟教程 

    从一个简单的类开始 

    class A():       #定义一个类 A

        a     = 100  #公有变量

        _b    = 200  #公有变量

        __c   = 300  #私有变量

        __d__ = 400  #公有变量

    a = A()     #实例化一个对象a,当然可以取另外一个名字b

    print(a.a,a._b,a.__c,a.__d__)   #打印四个变量的值

     

    运行结果: Traceback (most recent call last): File “c:\users\12090\desktop\a.py”, line 7, in  print(a.a,a._b,a.__c,a.d) AttributeError: ‘A’ object has no attribute ‘__c’ 

     

      

       

      

     

    运行结果,提示__c不能访问,这里的错误信息,并没有指出__c是私有变量,在类外不能访问 我们程序这样改动  

    通过成员函数间接访问私有变量 

     

    a=A,和a=A()的区别 

    我们把第8行改造一下: 去掉括号,就像这样:  

    a = A会成功生成对象a,而且通过对象a可以正确访问到公有变量a,_b,d。但是在调用函数print_c()的时候,出问题,错误提示 TypeError: print_c() missing 1 required positional argument: ‘self’ 提示缺少参数,怎么解决这个问题呢: 显示传递一个类,或者对象进去  那么a=A,和a=A()有什么区别呢? 区别是: 如果是a=A,则不会调用类中的构造函数; 如果是a=A(),则会调用构造函数; 

    A()会调用构造函数 

    我们来做一个实验, python中的构造函数名是系统规定的,init,添加后如下: 

    class A():       #定义一个类 A

        a     = 100  #公有变量

        _b    = 200  #公有变量

        __c   = 300  #私有变量

        __d__ = 400  #公有变量

        def __init__(self):   #构造函数定义

            print('calling __init__....')

        def print_c(self):  #通过成员函数访问私有变量

            return self.__c

    a = A          #不会调用构造函数

    print(a.a,a._b,a.print_c(a),a.__d__)

    b = A()        #会调用构造函数   

    print(b.a,b._b,b.print_c(),b.__d__)

     

    运行结果:  当我们通过A()这种形式构造对象的时候,会显示调用构造函数__init__。 当我们通过A这种形式构造对象的时候,不会调用构造函数。 

    构造函数,构造了什么 

    “构造”这个词,是一个动词,就是要造一个东西,那么造什么呢,其实我们上面的例子,可能让初学者有点不明所以,所以接下来,我们让构造函数做点有意义的事情,程序如下: 

    class A():       #定义一个类 A

        a     = 100  #公有变量

        _b    = 200  #公有变量

        __c   = 300  #私有变量

        __d__ = 400  #公有变量

        def __init__(self,a,b,c,d):   #通过构造函数给公有变量或者私有变量重新赋值

            print('构造前:',self.a,self._b,self.__c,self.__d__)

            self.a = a

            self._b = b

            self.__c = c

            self.__d__ = d

            print('构造后:',self.a,self._b,self.__c,self.__d__)

        def print_c(self):  #通过成员函数访问私有变量

            return self.__c

    a = A(1000,2000,3000,4000)          #通过传值构造对象

     

    运行结果:  这个例子,就证明了构造函数的作用 

    python中 self的作用 

    self这个单词是自己,自我的意思,它代表对象本身,其实你可以换一个单词也可以,比如you  

    照样可以运行 甚至一个地方用self,一个地方用you也可以  

    self的实际意义 

    我们一般使用self,python系统也默认是self,但是self的作用远不止单词意思这么简单 比如我们去掉self  

    运行起来,好像也没问题,但是这里的a,_b,__c,d(构造函数里面),并不是公有变量中的a,_b,__c,d。怎么见得呢? 我们把第七行打开  运行结果出错: Traceback (most recent call last): File “c:\users\12090\desktop\a.py”, line 13, in  a = A(1000,2000,3000,4000) #调用构造函数 File “c:\users\12090\desktop\a.py”, line 7, in init print(‘构造前:’,a,_b,__c,d) UnboundLocalError: local variable ‘_b’ referenced before assignment 

    错误原因,是本地变量_b没有引用,这个local是本地的意思,也就是在构造函数__init__函数作用范围内。那么第7行的a为什么没有报错呢,因为a用的是参数里面的a,并不是公有变量中a。 所以,第12行的打印结果,其实打印的是局部变量,也就是说,在构造函数里面我们定义了一套与公有变量同名的变量,在这种情况下,局部变量优先。 所以,self其实非常有作用,必须通过self来显示指定公有变量,不然会当作局部变量。 我们还可以进一步说明这个问题 

    进一步证明 

     

    结论 

    Python类中公有变量和私有变量定义一般定义在类名下面,构造函数上面,比如这样: class A: 公有变量 私有变量 def init(): 。。。 其中私有变量需要有前缀下划线__ 如果成员函数(包括构造函数),中出现了与公有变量(私有变量)同名的变量,则python系统会屏蔽公有变量和私有变量,把改变量当成局部变量。如果要在成员函数(包括构造函数)使用公有变量和私有变量,必须通过self显示指定,就像这样: class A: a = 100 _b = 200 __c = 300 def init(self,a,b,c): self.a = a #使用公有变量a _b = b #屏蔽了公有变量_b,重新定义了一个局部变量_b self.__c =c #使用私有变量__c

    展开全文
  • 主要介绍了Python类如何定义私有变量,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下
  • python—真假私有变量

    2021-01-20 03:07:49
    定义私有属性或方法加个__即可(双下划线) 先来定义对象的私有属性(方法一样) class Person(): def __init__(self, name, age): self.name = name self.__age = age def __str__(self): return {},{}.format...
  • Python类中的①私有变量/方法、②静态方法和③方法

    0. 引言

    在Python的类中,默认的定义为公开变量/方法,当然也可以定义私有变量私有方法,与其他语言不同的是,Python中使用__进行声明而非关键字进行声明。

    1. 私有属性和私有方法

    1.1 定义

    • 私有属性是指在 Python 的面向对象开发过程中,对象的某些属性只想在对象的内部被使用,但不想在外部被访问到这些属性。即,私有属性是对象不愿意公开的属性。
    • 私有方法是指在 Python 的面向对象开发过程中,对象的某些方法或者称为函数只想在对象的内部被使用,但不想在外部被访问到这些方法或函数。即:私有方法是对象不愿意公开的方法或函数。

    1.2 语法

    二者均使用开头__(两个下划线)进行定义:

    • 定义私有属性:self.__属性名 = xxx
    • 定义私有方法:def __方法名(参数)

    例子

    class Demo:
        def __init__(self, param_1, param_2):
            self.param_1 = param_1  # 定义公有属性
            self.__param_2 = param_2  # 定义私有属性
        
        # 定义私有方法
        def __secret_function(self):
            print(f"[公有属性] self.param_1: {self.param_1}")
            print(f"[私有属性] self.__param_2: {self.__param_2}")
    

    1.3 调用分析

    1.3.1 私有属性

    __init__的对象初始化方法中,以两个下划线开头定义的__param_1属性就是私有属性。现在在对象的外部来调用一下__param_1属性,看是否能正常访问该私有属性。

    class Demo:
        def __init__(self, param_1, param_2):
            self.param_1 = param_1  # 定义公有属性
            self.__param_2 = param_2  # 定义私有属性
        
        # 定义私有方法
        def __secret_function(self):
            print(f"[公有属性] self.param_1: {self.param_1}")
            print(f"[私有属性] self.__param_2: {self.__param_2}")
            
            
    ins_obj = Demo(param_1="公有属性", param_2="私有属性")
    print(ins_obj.param_1)
    print(ins_obj.__param_2)
    
    
    """
        公有属性
        ---------------------------------------------------------------------------
        AttributeError                            Traceback (most recent call last)
        Input In [20], in <cell line: 14>()
             12 ins_obj = Demo(param_1="公有属性", param_2="私有属性")
             13 print(ins_obj.param_1)
        ---> 14 print(ins_obj.__param_2)
    
        AttributeError: 'Demo' object has no attribute '__param_2'
    """
    

    从上图运行结果可以看出,第14行,即在对象外部访问对象的私有属性 __param_2 时,提示 AttributeError 错误,Demo对象 ins_obj 没有__param_2属性。


    为了证明ins_obj 类对象确实是有 self.__param_2 这个实例属性的,只是因为在对象外部不能访问私有属性。我把 self.__param_2 修改为self.param_2,结果如下:

    class Demo:
        def __init__(self, param_1, param_2):
            self.param_1 = param_1  # 定义公有属性
    #         self.__param_2 = param_2  # 定义私有属性
            self.param_2 = param_2  # 将私有属性改为公有属性
        
        # 定义私有方法
        def __secret_function(self):
            print(f"[公有属性] self.param_1: {self.param_1}")
            print(f"[私有属性] self.__param_2: {self.param_2}")
            
            
    ins_obj = Demo(param_1="公有属性", param_2="私有方法 -> 公有属性")
    print(ins_obj.param_1)
    print(ins_obj.param_2)
    
    
    """
        公有属性
        私有方法 -> 公有属性
    """
    

    可以从运行结果看出,这种公有属性在外部的调用是正常的,没有提示 AttributeError 错误。

    1.3.2 私有方法

    __secret_function(self) 实例方法中,以两个下划线开头定义的__secret_function(self) 方法就是私有方法。和上面测试流程一样,先在对象的外部来调用私有方法__secret_function(self) ,看是否能正常调用该私有方法。

    class Demo:
        def __init__(self, param_1, param_2):
            self.param_1 = param_1  # 定义公有属性
            self.__param_2 = param_2  # 定义私有属性
        
        # 定义私有方法
        def __secret_function(self):
            print(f"[公有属性] self.param_1: {self.param_1}")
            print(f"[私有属性] self.__param_2: {self.__param_2}")
            
            
    ins_obj = Demo(param_1="公有属性", param_2="私有属性")
    print(ins_obj.param_1)
    try:
        print(ins_obj.__param_2)
    except Exception as e:
        print(f"在调用私有属性时发生错误: {e}")
        
    # 调用私有方法
    ins_obj.__secret_function()
    
    
    """
        公有属性
        在调用私有属性时发生错误: 'Demo' object has no attribute '__param_2'
        ---------------------------------------------------------------------------
        AttributeError                            Traceback (most recent call last)
        Input In [22], in <cell line: 20>()
             17     print(f"在调用私有属性时发生错误: {e}")
             19 # 调用私有方法
        ---> 20 ins_obj.__secret_function()
    
        AttributeError: 'Demo' object has no attribute '__secret_function'
    """
    

    从上图运行结果可以看出,第20行,即在对象外部访问对象的私有方法__secret_function(self) 时,提示 AttributeError 错误,Demo 对象 ins_obj 没有 __secret_function(self) 方法。

    为了证明 Demo 类对象是有 __secret_function(self) 这个实例方法的,只是因为在对象外部不能访问私有方法。把__secret_function(self) 方法修改为:secret_function(self) ,其他代码不变,看如下的运行结果。

    class Demo:
        def __init__(self, param_1, param_2):
            self.param_1 = param_1  # 定义公有属性
            self.__param_2 = param_2  # 定义私有属性
        
        # 定义私有方法
        def secret_function(self):  # 将私有方法改为公有方法
            print(f"[公有属性——类内部调用] self.param_1: {self.param_1}")
            print(f"[私有属性——类内部调用] self.__param_2: {self.__param_2}")
            
            
    ins_obj = Demo(param_1="公有属性", param_2="私有属性")
    print(f"[类外部调用] ins_obj.param_1: {ins_obj.param_1}")
    try:
        print(f"[类外部调用] ins_obj.__param_2: {ins_obj.__param_2}")
    except Exception as e:
        print(f"在调用私有属性时发生错误: {e}")
        
    # 调用公有方法
    ins_obj.secret_function()
    
    
    """
        [类外部调用] ins_obj.param_1: 公有属性
        在调用私有属性时发生错误: 'Demo' object has no attribute '__param_2'
        [公有属性——类内部调用] self.param_1: 公有属性
        [私有属性——类内部调用] self.__param_2: 私有属性
    """
    

    可以从运行结果看出,这种非私有方法在外部的调用是正常的,没有提示 AttributeError 错误。

    1.3.3 类内部调用私有属性/方法

    在对象内部私有方法与私有属性是可以被调用的,证明如下:

    class Demo:
        def __init__(self, param_1, param_2):
            self.param_1 = param_1  # 定义公有属性
            self.__param_2 = param_2  # 定义私有属性
        
        # 定义私有方法
        def __secret_function(self):  # 私有方法
            print(f"[公有属性——类内部调用] self.param_1: {self.param_1}")
            print(f"[私有属性——类内部调用] self.__param_2: {self.__param_2}")
        
        # 定义公有方法并在公有方法中调用私有方法和私有属性
        def public_function(self):  # 公有方法
            # 分别调用公有属性和私有属性
            print(f"[public_function内部调用] self.param_1: {self.param_1}")
            print(f"[public_function内部调用] self.__param_2: {self.__param_2}")
            
            # 调用私有方法
            self.__secret_function()
            
            
    ins_obj = Demo(param_1="公有属性", param_2="私有属性")
    print(f"[类外部调用] ins_obj.param_1: {ins_obj.param_1}")
    try:
        print(f"[类外部调用] ins_obj.__param_2: {ins_obj.__param_2}")
    except Exception as e:
        print(f"在调用私有属性时发生错误: {e}")
    
    # 调用类的私有方法
    try:
        ins_obj.__secret_function()
    except Exception as e:
        print(f"在调用私有方法时发生错误: {e}")
        
    # 调用公有方法
    ins_obj.public_function()
    
    
    """
        [类外部调用] ins_obj.param_1: 公有属性
        在调用私有属性时发生错误: 'Demo' object has no attribute '__param_2'
        在调用私有方法时发生错误: 'Demo' object has no attribute '__secret_function'
        [public_function内部调用] self.param_1: 公有属性
        [public_function内部调用] self.__param_2: 私有属性
        [公有属性——类内部调用] self.param_1: 公有属性
        [私有属性——类内部调用] self.__param_2: 私有属性
    """
    

    上述代码中,public_function公有方法调用了私有属性self.__param_2和私有方法__secret_function(self)。说明在对象外部可以通过调用对象的公有方法去访问私有属性和私有方法(前提是得在类的内部定义好相关的代码)。

    在类的内部,私有属性和私有方法是可以随意被调用的,一旦到了类的外部,那就不能调用了

    1.3.4 子类 内部/外部 调用私有属性/方法

    class Demo:
        def __init__(self, param_1, param_2):
            self.param_1 = param_1  # 定义公有属性
            self.__param_2 = param_2  # 定义私有属性
        
        # 定义私有方法
        def __secret_function(self):  # 私有方法
            print(f"[公有属性——类内部调用] self.param_1: {self.param_1}")
            print(f"[私有属性——类内部调用] self.__param_2: {self.__param_2}")
        
        # 定义公有方法并在公有方法中调用私有方法和私有属性
        def public_function(self):  # 公有方法
            # 分别调用公有属性和私有属性
            print(f"[public_function内部调用] self.param_1: {self.param_1}")
            print(f"[public_function内部调用] self.__param_2: {self.__param_2}")
            
            # 调用私有方法
            self.__secret_function()
            
    class Demo_child(Demo):
        # 继承Demo的一切
        # 定义公有方法访问父类的私有属性和方法
        def public_child(self):
            # 分别调用公有属性和私有属性
            print(f"[public_child内部调用] self.param_1: {self.param_1}")
            print(f"[public_child内部调用] self.__param_2: {self.__param_2}")
            
            # 调用私有方法
            self.__secret_function()
            
            
    child_obj = Demo_child(param_1="Re-公有属性", param_2="Re-私有属性")
    print(f"[成功] [类外部调用-子类调用父类公有属性] child_obj.param_1: {child_obj.param_1}")
    try:
        print(f"[成功] [类外部调用-子类调用父类私有属性] child_obj.__param_2: {child_obj.__param_2}")
    except Exception as e:
        print(f"[失败] 子类调用父类私有属性时发生错误: {e}")
    
    # 子类调用父类的私有方法
    try:
        print("......................[开始] 子类调用父类的私有方法......................")
        child_obj.__secret_function()
        print("[成功] 子类调用父类的私有方法")
    except Exception as e:
        print(f"[失败] 子类调用父类的私有方法时发生错误: {e}")
        
    # 子类调用父类的公有方法
    try:
        print("......................[开始] 子类调用父类的公有方法......................")
        child_obj.public_function()
        print("[成功] 子类调用父类的公有方法")
    except Exception as e:
        print(f"[失败]子类调用父类的公有方法时发生错误: {e}")
    
    # 子类调用自己的公有方法
    try:
        print("......................[开始] 子类调用自己的公有方法......................")
        child_obj.public_child()
        print("[成功] 子类调用自己的公有方法")
    except Exception as e:
        print(f"[失败] 子类调用自己的公有方法时发生错误: {e}")
        
    
    """
        [成功] [类外部调用-子类调用父类公有属性] child_obj.param_1: Re-公有属性
        [失败] 子类调用父类私有属性时发生错误: 'Demo_child' object has no attribute '__param_2'
        ......................[开始] 子类调用父类的私有方法......................
        [失败] 子类调用父类的私有方法时发生错误: 'Demo_child' object has no attribute '__secret_function'
        ......................[开始] 子类调用父类的公有方法......................
        [public_function内部调用] self.param_1: Re-公有属性
        [public_function内部调用] self.__param_2: Re-私有属性
        [公有属性——类内部调用] self.param_1: Re-公有属性
        [私有属性——类内部调用] self.__param_2: Re-私有属性
        [成功] 子类调用父类的公有方法
        ......................[开始] 子类调用自己的公有方法......................
        [public_child内部调用] self.param_1: Re-公有属性
        [失败] 子类调用自己的公有方法时发生错误: 'Demo_child' object has no attribute '_Demo_child__param_2'
    """
    

    可以看到,子类可以调用:

    1. 父类的公有属性
    2. 父类的公有方法(无论该公有方法是否调用父类的私有方法/属性)
    3. 子类的公有方法(里面不能直接调用父类的私有方法!)

    子类不能直接调用父类的私有方法和私有属性,但可以通过调用父类的公有方法间接访问父类的私有方法(即该父类的公有方法调用了父类的私有方法)。

    1.4 Python 伪·私有属性和私有方法

    在 Python 中,并没有真正意义上的私有,之所以上面的例子中我们无法访问在外部访问私有方法和私有属性,是因为 Python 内部在给属性、方法命名时,对名称做了一些特殊处理,使得外界无法访问到对应的属性和方法。

    以私有属性和私有方法为例,Python内部处理方式为:

    1. 属性: __param_1,经过处理后的属性名为:_Demo__param_1 ,即_类名__属性名
    2. 方法: __secret_function,经过处理后的方法名为:_Demo__secret_function,即_类名__方法名

    知道了 Python 内部对于私有属性和私有方法的处理,现在使用这种处理后的命名方式来在对象外部访问私有属性和私有方法,看是否能访问正常。

    class Demo:
        def __init__(self, param_1, param_2):
            self.param_1 = param_1  # 定义公有属性
            self.__param_2 = param_2  # 定义私有属性
        
        # 定义私有方法
        def __secret_function(self):  # 私有方法
            print(f"[公有属性——类内部调用] self.param_1: {self.param_1}")
            print(f"[私有属性——类内部调用] self.__param_2: {self.__param_2}")
        
        # 定义公有方法并在公有方法中调用私有方法和私有属性
        def public_function(self):  # 公有方法
            # 分别调用公有属性和私有属性
            print(f"[public_function内部调用] self.param_1: {self.param_1}")
            print(f"[public_function内部调用] self.__param_2: {self.__param_2}")
            
            # 调用私有方法
            self.__secret_function()
            
    
    ins_obj = Demo(param_1="公有属性", param_2="私有属性")
    print(f"[成功] [类外部调用公有属性] ins_obj.param_1: {ins_obj.param_1}")
    
    try:
        print(f"[成功] [类外部调用私有属性] ins_obj.__param_2: {ins_obj._Demo__param_2}")
    except Exception as e:
        print(f"[失败] 类外部调用私有属性时发生错误: {e}")
    
    # 调用私有方法
    try:
        ins_obj._Demo__secret_function()
        print("[成功] 类外部调用私有方法")
    except Exception as e:
        print(f"[失败] 类外部调用私有方法时发生错误: {e}")
        
        
    """
        [成功] [类外部调用公有属性] ins_obj.param_1: 公有属性
        [成功] [类外部调用私有属性] ins_obj.__param_2: 私有属性
        [公有属性——类内部调用] self.param_1: 公有属性
        [私有属性——类内部调用] self.__param_2: 私有属性
        [成功] 类外部调用私有方法
    """
    

    控制台没有抛任何的异常,之前的提示 AttributeError 错误也没有了。

    这个例子证明了 Python 是没有真正意义上的私有的,当知道了其内部处理方式后,依然可以使用实例对象._类名__属性名(方法名)的方法来在对象外部访问到对象内部定义的私有属性和私有方法

    但这种方式在日常工作中是不推荐使用的,既然在对象内部定义属性和方法时,就声明了其为私有的,调用方就需要遵守其规则

    2. 实例方法、静态方法和类方法

    2.1 实例方法/对象方法

    实例方法或者叫对象方法,指的是我们在类中定义的普通方法。只有实例化对象之后才可以使用的方法,该方法的第一个形参接收的一定是对象本身self

    说白了实例化方法就是我们最常用的方法,例子如下:

    class Demo:
        # 定义一个实例方法(对象方法)
        def ins_func(self):  # 对于实例方法,self不能省略
            print("这是一个[实例方法]")
            
    
    # [实例化方法] 方法1:实例化对象 -> 变量接收 -> 变量.调用实例方法
    ins_obj = Demo()
    ins_obj.ins_func()
    
    # [实例化方法] 方法2:实例化对象.调用实例方法(没有实例化对象的接收变量)
    Demo().ins_func()  # Demo的()就说明实例化对象了!
    
    
    """
        这是一个[实例方法]
        这是一个[实例方法]
    """
    

    2.2 静态方法

    1. 格式:在方法上面添加 @staticmethod
    2. 参数:静态方法可以有参数也可以无参数
    3. 应用场景:一般用于和类对象以及实例对象无关的代码
    4. 使用方式类名.类方法名(或者对象名.类方法名)

    例子

    class Demo:
        # 定义一个实例方法(对象方法)
        def ins_func(self):  # 对于实例方法,self不能省略
            print("这是一个[实例方法]")
            
        # 定义一个静态方法
        @staticmethod
        def static_method():  # 参数可有可无
            print("这是一个[静态方法]")
            
    
    # [实例化方法] 方法1:实例化对象 -> 变量接收 -> 变量.调用实例方法
    ins_obj = Demo()
    ins_obj.ins_func()
    
    # [实例化方法] 方法2:实例化对象.调用实例方法(没有实例化对象的接收变量)
    Demo().ins_func()  # Demo的()就说明实例化对象了!
    
    
    
    # [静态方法] 不用实例化对象,直接调用静态方法
    Demo.static_method()
    # Demo().static_method()  # 也不报错,但一般不这么用(因为会实例化对象)
    
    
    """
        这是一个[实例方法]
        这是一个[实例方法]
        这是一个[静态方法]
    """
    

    2.3 类方法

    类方法无需实例化,可以通过类直接调用的方法,但是方法的第一个参数接收的一定是类本身cls

    1. 在方法上面添加@classmethod
    2. 方法的参数为 cls 也可以是其他名称,但是一般默认为cls
    3. cls 指向 类对象
    4. 应用场景:当一个方法中只涉及到静态属性的时候可以使用类方法(类方法用来修改类属性)
    5. 使用方法(两种均可):
      1. 对象名.类方法名
      2. 类名.类方法名

    例子

    class Demo:
        # 0. 定义一个类属性
        __private_attr = 1
        
        
        # 1. 定义一个实例方法(对象方法)
        def ins_func(self, param_ins):  # 对于实例方法,self不能省略
            self.param_ins = param_ins
            print(f"这是一个[实例方法]: {self.param_ins}")
            
        # 2. 定义一个静态方法
        @staticmethod
        def static_method(param_static):  # 参数可有可无
            print(f"这是一个[静态方法]: {param_static}")
            
        # 3. 定义一个类方法
        @classmethod
        def class_method(cls, param_cls):
            print(f"这是一个[类方法]: {param_cls}")
            print(f"[修改前]类属性为: {cls.__private_attr}")
            cls.__private_attr = param_cls
            print(f"[修改后]类属性为: {cls.__private_attr}\n")
            
            try:        
                print(f"[修改前]类属性self.param_ins为: {cls.param_ins}")
                cls.param_ins = param_cls
                print(f"[修改后]类属性self.param_ins为: {cls.param_ins}")
            except Exception as e:
                print("类方法只能修改类属性,不能修改实例方法的类属性!")
            
            
    
    # [实例化方法] 方法1:实例化对象 -> 变量接收 -> 变量.调用实例方法
    ins_obj = Demo()
    ins_obj.ins_func(param_ins = "实例方法ins_func传入的参数")
    
    # [实例化方法] 方法2:实例化对象.调用实例方法(没有实例化对象的接收变量)
    Demo().ins_func(param_ins = "实例方法ins_func传入的参数")  # Demo的()就说明实例化对象了!
    
    
    
    # [静态方法] 不用实例化对象,直接调用静态方法
    Demo.static_method(param_static="静态方法static_method传入的参数")
    # Demo().static_method(param_static="静态方法static_method传入的参数")  # 也不报错,但一般不这么用(因为会实例化对象)
    
    
    # [类方法] 方法1:对象名.类方法名
    ins_obj.class_method(100)
    
    # [类方法] 方法2:类名.类方法名
    Demo.class_method(100)
    
    
    """
        这是一个[实例方法]: 实例方法ins_func传入的参数
        这是一个[实例方法]: 实例方法ins_func传入的参数
        这是一个[静态方法]: 静态方法static_method传入的参数
        这是一个[类方法]: 100
        [修改前]类属性为: 1
        [修改后]类属性为: 100
    
        类方法只能修改类属性,不能修改实例方法的类属性!
        这是一个[类方法]: 100
        [修改前]类属性为: 100
        [修改后]类属性为: 100
    
        类方法只能修改类属性,不能修改实例方法的类属性!
    """
    

    参考

    1. https://www.jb51.net/article/239280.htm
    2. https://blog.csdn.net/weixin_39898248/article/details/109935893
    展开全文
  • 公共变量Python不会限制我们访问python程序的任何变量或调用任何成员方法。默认情况下,所有python变量和方法在Python中都是公共的。因此,当我们要公开任何变量或方法时,我们什么也不做。让我们看下面的例子-...
  • 我们知道,类中私有变量是不能直接在外访问或修改的,因此我们可以设置一个get函数和一个set函数来间接访问和修改私有属性,那么每次访问和修改的都需要调用函数,有没有更简单的方法呢?下面介绍两种方法: 1. ...
  • Python类中私有变量和公有变量

    千次阅读 2020-07-30 14:20:25
    我们这里就直奔主题,不做基础铺垫,默认你有一些Python类的基础,大家在看这篇博客的... __c = 300 #私有变量 __d__ = 400 #公有变量 a = A() #实例化一个对象a print(a.a,a._b,a.__c,a.__d__) #打印四个变量的值 运
  • [Python]Python中私有变量
  • 1.私有变量:class A(object):_name='ling'__sex='F'def hello(self):print(self._name)通过在属性变量名前加上双下划线定义属性为私有属性;1._XX以单下划线开头的表示的是protected类型的变量,即保护类型只能...
  • 一.Python类中私有变量和私有方法: 在Python中可以通过在属性变量名前加上双下划线定义属性为私有属性 特殊变量命名: 4、私有变量和属性只在自己的类中使用,在实例化对象不能调用; 受保护类型的则可以实例...
  • python中私有变量为伪私有变量。以下有两种方法对其进行访问。 方法1: 方法2:_类名 __变量名
  • 无法被实例化对象调用的类中的函数与变量的内部可以调用私有函数与私有变量定义私有函数与私有变量的目的只希望的内部业务调用使用,不希望被使用者调用在变量或函数前添加两个__(下划线)self.__age=33#私有...
  • 0 引言 ...如私有变量、共有变量、全局变量、局部变量等。这里给大家介绍Python类(class)的变量之间的区别。参考代码: class G(): fly = False #类中的全局变量 def __init__(self): selg....
  • python中类私有变量可以修改吗

    千次阅读 2020-03-13 13:43:16
    python类中,以__开头的变量是私有变量,以_开头的变量是受保护的变量,不需要用private或者ptotect声明,这一点与C++是不一样的。 在python中私有变量是可以修改的,来看下面几个例子。 总结一下: 1、...
  • python中继承时,私有变量出现以下错误:AttributeError: 'dog' object has no attribute '_dog__name'我找了很多东西,但不知道我的问题在哪里class animal(object):__name = ""__height = ""__weight = ""__...
  • 主要介绍了Python面向对象程序设计中类的定义、实例化、封装及私有变量/方法,结合具体实例形式较为详细的分析了Python面向对象程序设计中类的定义、实例化、封装、私有变量、私有方法等相关使用技巧,需要的朋友可以...
  • Python私有变量与私有方法

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 56,687
精华内容 22,674
关键字:

python类中的私有变量