python 类的使用(7)之类的私有属性和方法 (类中以单下划线或双下划线开头的变量名或函数名)

在python中有时候会发现别人写的代码中会有一些函数或者变量是以下划线开头的,这些情况又主要出现在类中,其中既有单下划线,也有双下划线,这种以下划线开头的函数或者变量实际上就是代表“私有”的意思,在python中私有变量不需要额外的像其它某些语言中还需要使用private关键词,在python中使用下划线开始命名类中的函数或者变量即可表示私有。那么单下划线和双下划线开头的具体意义以及区别分别是什么呢?若有兴趣请看本文细细为您分析!

附上类使用专栏的其它文章的链接:


以单下划线开头的函数或变量(类中)

以单下划线开头的函数或者变量实际上是伪私有,在类中定义的加单下划线的函数或者属性都是可以被类外部所访问到的。以单下划线开头的函数或变量的意义对我们来说就是虽说其能够被访问,但是最好不要访问(这种伪私有属性或方法的含义就是告诉我们使用这个类的人最好不要直接调用它)。

举个简单的例子:

class Animal:
    _type = 'cute'
    # 定义了一个以单下划线开头的类属性
    def __init__(self):
        self._age = 3
        # 这里也有一个以单下划线开头的类属性
        self.name = 'xiaobai'
    
    def _show_info(self):
    # 定义了一个以单下划线开头的函数
        return self.name, self._age

a = Animal()
print(a._show_info(),a._type, a._age)
# 这里直接调用函数和直接调用两个属性
# 结果:('xiaobai', 3) cute 3
# 可以看到是像普通的属性或方法一样调用就行了

除了上面正常调用外,类的继承时父类的以单下划线开头的属性以及方法也都会被继承。在某些博客中看到说这种命名的方式在使用from module import 类名时会出错,但是我试了没什么问题,但也不知道是不是我有什么误解。

以双下划线开头的函数或变量(类中)

在一个类中,不乏有以双下划线包围的函数,这些函数之前我已经介绍过了,它们就是类的魔法方法,而单纯以双下划线开头的函数或变量代表的是python类中真正的私有方法或属性,这些方法或者属性在类的外部是不能被访问到的。也就是不能被以这种类名.__变量名类名__函数名的形式被访问到,同时类的继承中,这些私有属性及私有方法也不能被继承,但在类的内部这些私有属性和方法是可以被访问到的,因此可以通过间接的方法来设置、访问这些私有变量或函数。

先看一个简单的例子:

class City:
    def __init__(self):
        self.__name = 'Beijing'
        # 这里设置一个私有变量
        self.area = 16410.54
   
    def show_area(self):
        print(self.area)
            
    def __show_area(self):
        print(self.area)
        
a = City() 
a.show_area()   # 结果:16410.54
a.__show_area() # 报错:'City' object has no attribute '__show_area'
print(a.__name) # 报错:'City' object has no attribute '__name'
# 根据上面的结果,确实是能看出以双下划线开头的属性和方法确实是真正的私有变量



# ok,接下来举个在类内部使用这些私有属性或方法的例子:
class City:
    def __init__(self):
        self.__name = 'Beijing'
        # 这里设置一个私有变量
        self.area = 16410.54
    
    def __show_area(self):
        return self.area
    
    def show_name_and_area(self):
        print(self.__name, self.__show_area)
        
    def change_name(self, new_name):
        self.__name = new_name
      
a = City() 
a.show_name_and_area()  
# 运行结果:Beijing 16410.54
a.change_name('BJ')
# 这里修改内部的私有变量
a.show_name_and_area()  
# 运行结果:BJ 16410.54
# 私有变量被成功修改,可以看到在类的内部调用还是很有用的



# 接下来看一下在类继承时的情况:
class City:
    def __init__(self):
        self.__name = 'Beijing'
        # 这里设置一个私有变量
        self.area = 16410.54
    
    def __show_area(self):
        print(self.area)   
          
class A:
    pass

a = A()
a.__show_area()  # 报错:'A' object has no attribute '__show_area'
print(a.area)    # 结果:16410.54
print(a.__name)  # 报错:'A' object has no attribute '__name'
# 可以根据上述结果证明类的继承时私有方法和属性是不会被继承的,
# 这也使继承时不易发生变量名或函数名的冲突

当然并不是说一定不能访问到私有变量,python中是使用name mangling技术处理类中函数或变量名的,即__name替换成 _class__name,在类外部这样调用就行了,如下:

# 接上个例子
a = City()
a._City__show_area()

当然这种使用方式是不推荐的,毕竟被设置为私有的变量或函数肯定是有原因的,因此正常情况下不要使用这种方式去调用。

不在类中的下划线在函数名或变量名两侧的情况

这种情况实际上较少出现,但是也简单说一下吧,其实它们就是普通的全局变量或者函数,可以在任意地方被调用,我尝试了一下在函数名或变量名的两侧加好几个下划线都没问题,都可以正常调用的,当然平常我们不会这样用(没什么意义,看起来也很乱)。但是有时候为了与python中的保留字不冲突,可能会加下划线来区分,如class_可以与class关键字区分开。

参考:python 私有属性和方法
参考:python变量前的单下划线(私有变量)和双下划线()

  • 2
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
当我们需要在派生类中新增私有属性并重写基方法时,可以使用以下步骤: 1. 定义一个派生,并在定义的开头使用称和圆括号,以便将基与派生联系起来。 2. 在派生类中定义一个新的私有属性。 3. 在派生类中重写基方法,可以使用 super() 函数调用基方法,并在其基础上添加新的功能。 下面是一个示例代码,演示了如何在 Python 中实现派生私有属性和重写基方法: ```python class BaseClass: def __init__(self, name): self.name = name def display(self): print("BaseClass Name:", self.name) class DerivedClass(BaseClass): def __init__(self, name, age): super().__init__(name) self.__age = age # 新增私有属性 def display(self): super().display() # 调用基方法 print("DerivedClass Age:", self.__age) # 添加新功能 d = DerivedClass("Tom", 20) d.display() ``` 在这个例子中,我们创建了一个基 BaseClass,其中包含一个属性和一个方法。然后我们创建了一个派生 DerivedClass,它继承了 BaseClass,并添加了一个新的私有属性。最后,我们重写了基方法,并在其中添加了新的功能。 需要注意的是,在派生类中新增私有属性时,需要在属性称前加上两个下划线,这样属性就变成了私有属性,只能在内部访问。另外,当我们重写基方法时,可以使用 super() 函数调用基方法,并在其基础上添加新的功能。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值