玩转Python类的(私有)属性与方法的使用
Posted 涤生大数据
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了玩转Python类的(私有)属性与方法的使用相关的知识,希望对你有一定的参考价值。
1.Python中属性:类属性 ,实例属性,私有属性的使用
在Python中的属性分为:类属性和对象(实例)属性:
1.类属性就是属于类所有,可以直接用类名.属性名直接调用,类的属性在内存中只有一份。实例属性就是在__init__()方法中初始化的属性;
2.实例属性属于类的对象所有,可以用对象名.属性名的形式进行调用,但是不能用类名.属性名进行调用 。因为实例属性只有在实例创建时,才会初始化创建。
#1.类属性和实例的属性的调用关系
class Person:
country ="china" #类属性
def __init__(self,name,age):
sex ="男" #这不是实例属性,只是变量而已,用对象名.sex调不出来。
self.name = name #实例属性
self.age = age
#创建对象
print(Person.country)
#print(Person.age) 出错,AttributeError: type object 'Person' has no attribute 'age'
p1 = Person("tom",12)
print(p1.country,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
-------创建对象-------------------------------------------------------------------------
p1.country = "america" #注意如试图通过实例去修改类属性,则会创建一个同名的实例属性。
print(p1.country) #通过实例去修改属性,实例的属性修改了:america,注意这里修改的不是类属性,只是同名的实例属性
print(Person.country)#但是类的属性还是没有修改:china
Person.country = "japan" #只有用类名.属性名才能修改类的属性值。
p2= Person("jack",11)
print("p1.country:",p1.country)
print("p2.country",p2.country)
print("Person.country",Person.country)
------结果如下-----------------------------------------------------------------------------
america
china
p1.country: america
p2.country japan
Person.country japan
实际开发中为了程序的安全,关于类的属性都会封装起来,Python中为了更好的保存属性安全,即不能随意修改。一般属性的处理方式为:1.将属性定义为私有属性。2.添加一个可以调用的方法,供调用。
特别注意:
- 1.要访问类属性有两种方式:
- 类名.类属性
- 对象.类属性 (不推荐)
- 如果使用
对象.类属性 = 值
赋值语句,只会 给对象添加一个属性,而不会影响到 类属性的值
- 2.类属性和实例属性的本质区别
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内存地址:",id(stu1.getAge()))
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.私有方法,类方法,静态方法的使用
python类中方法包括:实例方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
- 实例方法:由对象调用;至少一个self参数;执行实例方法时,自动将调用该方法的对象赋值给self;
- 类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类赋值给cls;
- 静态方法:由类调用;无默认参数;
1.私有方法:以 __两个下划线开头,声明该方法为私有方法,只能在类的内部调用 (类内部别的方法可以调用他),不能在类地外部调用。
class 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):
return cls.country
@classmethod
def sum(cls,a,b):
return a+b
p = People()
print (p.getCountry()) #可以用过实例对象引用
print (People.getCountry() ) #可以通过类名.方法名的形式调用
print(p.sum(10,11))
print(People.sum(10,11))
====================================================================================
china
china
21
21
3.静态方法:需要通过修饰器@staticmethod
来进行修饰,静态方法不需要多定义参数
-
在开发时,如果需要在 类 中封装一个方法,这个方法:
- 既 不需要 访问 实例属性 或者调用 实例方法
- 也 不需要 访问 类属性 或者调用 类方法
-
这个时候,可以把这个方法封装成一个 静态方法
class Game(object):
# 游戏最高分,类属性
top_score = 0
@staticmethod
def show_help():
print("帮助信息:让僵尸走进房间")
@classmethod
def show_top_score(cls):
print("游戏最高分是 %d" % cls.top_score)
def __init__(self, player_name):
self.player_name = player_name
def start_game(self):
print("[%s] 开始游戏..." % self.player_name)
# 使用类名.修改历史最高分
Game.top_score = 999
# 1. 查看游戏帮助
Game.show_help()
# 2. 查看游戏最高分
Game.show_top_score()
# 3. 创建游戏对象,开始游戏
game = Game("小明")
game.start_game()
# 4. 游戏结束,查看游戏最高分
Game.show_top_score()
3.方法的使用注意要点
注意python中不支持方法的重载:即方法名相同,参数类型(参数个数不同)不同的函数,python中 不支持。
def p():
print("dd")
def p(a,b):
print("dd")
def p(a):
print("dd")
p()#报错,因为python中不需要定义参数的类型。如果有多个重载的函数,则python默认只能使用最后一个有效。
所以只能调用P(a)这个函数
统一声明:关于原创博客内容,可能会有部分内容参考自互联网,如有原创链接会声明引用;如找不到原创链接,在此声明如有侵权请联系删除哈。关于转载博客,如有原创链接会声明;如找不到原创链接,在此声明如有侵权请联系删除哈。
以上是关于玩转Python类的(私有)属性与方法的使用的主要内容,如果未能解决你的问题,请参考以下文章