Python类的私有属性与私有⽅法的使⽤
xx: 公有变量
_x: 单前置下划线,私有化属性或⽅法,from somemodule import 禁⽌导⼊,类对象和⼦类可以访问【另解:前置单下划线,⼜称⼝头私有变量,私有化属性或⽅法的⼀种,⼀般来讲,变量名_xx被看作是“私有的”,在模块或类外不可以使⽤。当变量是私有的时候,⽤_xx 来表⽰变量是很好的习惯。类对象和⼦类可以访问,这并不能完全做到真正的私有,只是约定俗成的⽽已,这样写表⽰不希望这个变量在外部被直接调⽤】
__xx:双前置下划线,避免与⼦类中的属性命名冲突,⽆法在外部直接访问(名字重整所以访问不到)【__xx:前置双下划线,私有化属性或⽅法,只有内部可以访问,外部不能访问。】
__xx__:双前后下划线,⽤户名字空间的魔法对象或属性。例如:init , __ 不要⾃⼰发明这样的名字【__xx__:以双下划线开头,并且以双下划线结尾的,是特殊变量(这就是在python中强⼤的魔法⽅法),特殊变量是可以直接访问的,对于普通的变量应当避免这种命名风格。】xx:单后置下划线,⽤于避免与Python关键词的冲突
通过name mangling(名字重整(⽬的就是以防⼦类意外重写基类的⽅法或者属性)如:_Class__object)机制就可以访问private了。
#coding=utf-8
class Person(object):
def__init__(self, name, age, taste):
self.name = name
self._age = age
self.__taste = taste
def showperson(self):
print(self.name)
print(self._age)
print(self.__taste)
def dowork(self):
self._work()
self.__away()
def _work(self):
print('my _work')
def__away(self):
print('my __away')
class Student(Person):
def construction(self, name, age, taste):
self.name = name
self._age = age
self.__taste = taste
def showstudent(self):
print(self.name)
print(self._age)
print(self.__taste)
@staticmethod
def testbug():
_Bug.showbug()
# 模块内可以访问,当from  cur_module import *时,不导⼊
class _Bug(object):
@staticmethod
def showbug():
print("showbug")
s1 = Student('jack', 25, 'football')
s1.showperson()
print('*'*20)
# ⽆法访问__taste,导致报错
# s1.showstudent()
s1.showperson()
print('*'*20)
s1.showstudent()
print('*'*20)
----------------------------------------------讲解----------------------------------------------------------------------------------------
1.Python中属性:类属性,实例属性,私有属性的使⽤
在Python中的属性分为:类属性和对象(实例)属性:
1.类属性就是属于类所有,可以直接⽤类名.属性名直接调⽤,类的属性在内存中只有⼀份。实例属性就是在__init__()⽅法中初始化的属性;
2.实例属性属于类的对象所有,可以⽤对象名.属性名的形式进⾏调⽤,但是不能⽤类名.属性名进⾏调⽤。因为实例属性只有在实例创建时,才会初始化创建。
#1.类属性和实例的属性的调⽤关系
class Person:
country ="china"#类属性
def__init__(self,name,age):
sex ="男"#这不是实例属性,只是变量⽽已,⽤对象名.sex调不出来。
self.name = name #实例属性
self.age = age
#创建对象
untry)
#print(Person.age) 出错,AttributeError: type object 'Person' has no attribute 'age'
p1 = Person("tom",12)
untry,p1.age,p1.name,p1)
----------结果如下------------------------------------------------------------------------
china
china 12 tom
----------------------------------------------------------------------------------------
#2.修改类属性和实例属性:类属性只能通过类名.属性才可以修改
class Person:
country ="china"#类属性
def__init__(self,name,age):
sex ="男"#这不是实例属性,只是变量⽽已,⽤对象名.sex调不出来。
self.name = name #实例属性
self.age = age
-------创建对象-------------------------------------------------------------------------
untry) #通过实例去修改属性,实例的属性修改了:america
untry)#但是类的属性还是没有修改:china
p2= Person("jack",11)
print("p1.country:",p1.country)
print("p2.country",p2.country)
print("untry",untry)
------结果如下-----------------------------------------------------------------------------
america
china
实际开发中为了程序的安全,关于类的属性都会封装起来,Python中为了更好的保存属性安全,即不能随意修改。⼀般属性的处理⽅式为:1.将属性定义为私有属性。2.添加⼀个可以调⽤的⽅法,供调⽤。
3.Python中⽤__两个下划线开头,声明该属性为私有,不能在类地外部被使⽤或直接访问
class Person1(object):
country ='china'#类属性
__language ="Chinese"#私有类属性也不能直接外部调⽤
def__init__(self,name,age):
self.name = name
self.__age = age  #使⽤__下划线表⽰私有属性,对象不能直接调⽤,要通过⽅法调调⽤
def getAge(self):
return self.__age
def setAge(self,age):
if age >100 or age <0:
print("age is not true")
else :
self.__age = age
def__str__(self):
info = "name :"+self.name +",age(保密):"+str(self.__age)  #注意这⾥不是self.age
return info
#------创建对象,调⽤⽅法,属性测试-------------------------------------------------------
stu1 =  Person1("tom",18)
print("修改前的结果:",stu1.__str__())
stu1.name="tom_2"#修改stu1的name属性
print("修改name后的结果:",stu1.__str__())
#print(stu1.__age)  #直接调⽤私有属性__age报错,'Person1' object has no attribute '__age'
print("打印私有age内存地址:",Age()))
stu1.__age = 19  #如果这样赋值的话,不会报错,因为系统不到这个变量,直接新建了⼀个。但是实际没有修改对象的属性值
print(stu1.__age) #有值,但是没有实际修改stu1对象的age属性值
print("打印stu1.__age的内存地:",id(stu1.__age)) #两个内存地址值不⼀样。
print("错误修改age后的值",stu1.__str__())  #实际值没有变
stu1.setAge(22) #只有调⽤才可以修改age的值
print("正确修改age后的值",stu1.__str__())
'''执⾏结果如下:
修改前的结果: name :tom,age(保密):18
修改name后的结果: name :tom_2,age(保密):18
打印私有age内存地址: 1388146224
19
打印stu1.__age的内存地: 1388146256
错误修改age后的值 name :tom_2,age(保密):18
正确修改age后的值 name :tom_2,age(保密):22
'''
2.私有⽅法,类⽅法,静态⽅法的使⽤
1.私有⽅法:以 __两个下划线开头,声明该⽅法为私有⽅法,只能在类的内部调⽤(类内部别的⽅法可以调⽤他),不能在类地外部调⽤。
lass Person5:
def__p(self):
print("这是私有属性") #内部函数也同样可以任意之间互相调⽤
def p1(self):
print("这是p1不是私有⽅法")
def p2(self):
print("这是p2,可以调⽤p1,也可以调⽤私有⽅法__p")
self.p1()
self.__p()
#创建对象
c1 = Person5()
c1.p1()
c1.p2()
#c1.__p() #不能直接私有函数。报错。注意区分系统⾃带的函数如__str__,外部可以直接调⽤的。
'''结果如下:
这是p1不是私有⽅法
这是p2,可以调⽤p1,也可以调⽤私有⽅法__p
这是p1不是私有⽅法
这是私有属性
'''
2.类⽅法的使⽤:是类所拥有的⽅法,需要⽤修饰器@classmethod来标识其为类⽅法,对于类⽅法,第⼀个参数必须是类对象,⼀般以cls 作为第⼀个参数,也可以有别的参数。但是第⼀个必须是类对象,类似类中的def定义的普通⽅法第⼀个参数要是self⼀样的道理
class People(object):
country = 'china'
#类⽅法,⽤classmethod来进⾏修饰,跟普通的⽅法区别就是可以直接通过类名.⽅法名的⽅式调⽤
@classmethod
def getCountry(cls):
untry
@classmethod
def sum(cls,a,b):
return a+b
p = People()
print (p.getCountry())  #可以⽤过实例对象引⽤
print (Country() )  #可以通过类名.⽅法名的形式调⽤
print(p.sum(10,11))
print(People.sum(10,11))
====================================================================================
china
china
21
21
3.静态⽅法:需要通过修饰器@staticmethod来进⾏修饰,静态⽅法不需要多定义参数
class People(object):
country = 'china'
@staticmethod
#静态⽅法,不⽤定义参数
def getCountry():
untry
print (Country())
3.⽅法的使⽤注意要点
注意python中不⽀持⽅法的重载:即⽅法名相同,参数类型(参数个数不同)不同的函数,python中不⽀持。def p():
print("dd")
def p(a,b):
print("dd")
python干嘛用的
def p(a):
print("dd")
p()#报错,因为python中不需要定义参数的类型。如果有多个重载的函数,则python默认只能使⽤最后⼀个有效。
所以只能调⽤P(a)这个函数

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。