核心语法-Python–Class语法02
实例变量与类变量
与Python类相关的变量有两类:实例变量和类变量。除此之外,实例方法中也可能使用一些中间变量,这些中间变量只能用在某个实例方法中,它们是普通变量。全局变量可以在所有的实例中均可使用。
1、实例变量
在实例方法中定义的非普通变量就是实例比哪里,又被称为“实例属性”。实例变量即可被定义它的方法所调用,也可被类中的其他方法所调用,调用的形式是:self.变量
实例变量不是只能由__init__()方法所定义的。
例如,在Gamer类中,定义了4个实例变量:表示姓名的变量 name ,表示编号的变量 number,表示性别的变量 sex,表示得分的变量 score,它们均由构造函数
(初始化方法)init()所定义的。当然,在其他实例方法中,同样可以定义实例变量。
如下:
class Mm(object):
def __init__(self,name):
self.name = name
def setmm(self,age):
self.age = age
def show(self):
print(self.name,self.age)
a1 = Mm('shh')
a1.setmm(34)
a1.show()
print(a1.name,a1.age)
上述举例中,用两种不同的定义方式定义了两个实例变量–name和age。实例变量可在类内或类外被实例引用。引用实例变量的方法由以下两种:
第1种:在类内引用实例变量的方法,它的语法形式为:self.实例变量
如 : self.name = ‘张君迎’
第2种:在类外引用实例变量的方法,它的语法形式为: 实例.实例变量
如 : a1 = Gamer(‘101’,‘Junying’,20)
a1.score += 10
2、类变量
所谓“类变量”,是指在类中单独被定义,但不是在类的任何方法内被定义的变量,又被称为“类属性”,它不同于实例属性。如在Gamer类中被定义的两个变量top_score与gamers均为类变量。
类变量可由类的所有实例共享。
类变量往往不像实例变量那样频繁地被引用。
类变量可在类内或类外被类所引用,但是类变量只能被类所引用。引用类变量的方法如下:
(1)类内引用类内变量 语法: cls.类变量
cls.gamers +=1
(2)类外引用类变量 语法:类.类变量
a1 = Gamer(‘101’,‘Junying’,20)
Gamer.gamers += 1
3、实例变量与类变量的关系
实例变量与类变量的关系如下:
(1)实例变量被每个实例所拥有,而且每个实例的实例变量相互独立;而类变量只能被类所拥有。
(2)如果实例变量与类变量重名,那么实例变量的优先级高于类变量的优先级。因此实例变量将屏蔽类变量。换言之,实例变量优先被使用。
私有属性和私有方法
1、私有属性和方法
如果一个属性名或方法名是由双下划线“__”开头的,那么该属性或方法就无法在类外被访问,它们被称为私有属性和私有方法
2、内置属性和方法
如果一个属性或方法以“xxx”形式被定义,即前后均有双下划线,那么该属性或方法可在类外被访问。在Python的类中,以“xxx”形式定义的属性和方法为特殊属性和特殊方法,
他们被称为内置属性和内置方法。
在一般情况下,不要以 “xxx”形式定义普通属性,
Python已经预定了多个特殊属性和特殊方法。所有Python类均有以下内置属性,并且可以像任何其他属性一样被访问。
dict:包含类的命名空间的字典
doc:包含类的命名空间的字典
name:类名
mmodule:定义类的模块名称。此属性下面在交互模式下的值为"main"
__bases————:一个包含基类的元组,元组元素按在基类列表中出现的顺序排列。
私有属性案例
以双下划线开头的属性是私有属性,因此在类外不能直接使用或访问该类属性。
class Mytester(object):
def __init__(self,dat1,dat2):
self.__dat1 = dat1 #私有属性
self.dat2 = dat2
def get_dat1(self):
return self.__dat1
if __name__ == '__main__':
test1 = Mytester(10,18)
print(test1.dat2)
"""
print(test1.__dat1)
File "D:\Python\pycharm\pycharm_code\Class_Python02.py", line 120, in <module>
print(test1.__dat1)
AttributeError: 'Mytester' object has no attribute '__dat1'
"""
print(test1._Mytester__dat1)
print(test1.get_dat1())
print(test1.__dict__)
在类外访问私有属性的两种方法:
1、
将print(test1.__dat1) 改为 print(test1._Mytester__dat1)
2、
将print(test1.__dat1) 改为 print(test1.get_dat1())
私有属性不能被继承
查看全部属性的方法
print(test1.__dict__)
虽然可以在类外访问私有属性,但是还是不要访问。可以直接认为在类外不可直接访问私有属性。记住就好!
私有方法
class Person(object):
def __init__(self):
self.__name ='张三' #私有属性
self.age = 22
def __get_name(self): #私有方法
return self.__name
def get_age(self): #公有方法
return self.age
if __name__ == '__main__':
p1 =Person()
print(p1.get_age())
"""
print(p1.__get_name())
Traceback (most recent call last):
File "D:\Python\pycharm\pycharm_code\Class_Python02.py", line 154, in <module>
print(p1.__get_name())
AttributeError: 'Person' object has no attribute '__get_name'
"""
建议,在类外不要使用私有属性和私有方法
类的使用
不带默认属性的类及其使用
创建一个类:
对象1 = 类(参数1,参数2,…)
通过以下形式访问实例或类的属性,调用实例或类的方法。
(1)访问实例属性的形式是:对象.实例属性
(2)访问类属性的形式是: 类.类属性
(3)调用实例方法的形式是: 对象.实例方法
(4)调用类方法的形式: 类.类方法或类.类静态方法
#案例
class Gamer(object):
"""
游戏玩家
某某某
"""
top_score = 0 #类变量
gamers = 0
#静态方法
@staticmethod
def show_help(): #不需要类变量和实例变量的方法
print("这是一个猜数的小游戏(1-100整数)")
print("可以同时有三个玩家")
print("谁最接近,谁得分最高")
print("如果完全一样,则得10分,误差在10%以内得8分,20%得6分")
print("误差在30%以内得5分,否则不得分")
#类方法
@classmethod
def show_top_score(cls):
print("游戏最高分是:%d"%cls.top_score)
@classmethod
def show_gamers(cls):
print("游戏玩家总数:%d"%cls.gamers)
def test():
print("kkkk")
#构造函数(对类的实例进行初始化)
def __init__(self,number,name,sex):
self.name = name
self.number = number
self.sex = sex
self.score = 0
Gamer.gamers += 1
#开始游戏方法
def start_game(self):
self.age = 16
print("{}开始游戏".format(self.name))
#实例计分方法
def add_score(self,score):
self.score += score
#获取实例得分方法
def get_score(self):
# self.add_score(s)
return self.score
Gamer.show_help() #调用类方法
a1 = Gamer("101",'Junying',18) #创建实例a1
a1.start_game() #调用实例方法
a1.add_score(10)
print(a1.get_score())
print(a1.add_score(10))
print(a1.get_score())
print(Gamer.gamers)
a2 = Gamer('102','Yd',19)
Gamer.show_top_score()
Gamer.show_gamers()
a1.age #访问实例属性
print(Gamer.__dict__)
print(Gamer.__doc__)
print(Gamer.__module__)
print(Gamer.top_score)
带默认属性的类及其使用
在定义类时,可对实例属性进行默认值设置。如果在调用方法时省略实际参数,那么相应的实例属性就被设置为默认值。
class Food(object):
"""
外卖类
#属性:顾客、地址、手机号、份数、折扣
"""
def __init__(self,name,address,moblile,discount=1): #默认不打折
self.name = name
self.address = address
self.mobile = moblile
self.discount = discount
#计算费用方法
def cacl_all(self,servings=1): #份数默认为1
return servings*10*self.discount
if __name__ == '__main__':
#顾客1
name = input("欢迎光临Junying饺子馆! 您好,您的名字:")
mobile = input("请问您的手机号:")
address =input("请问您的地址:")
servings = int(input("请问份数:"))
c1 = Food(name,address,mobile) #创建实例
print("份数:{}费用:{}".format(servings,c1.cacl_all(servings)))
#顾客2
name = input("欢迎光临Junying饺子馆!您好,您的名字:")
mobile = input("请问您的手机号:")
address = input("请问您的地址:")
servings = int(input("请问份数:"))
c2 = Food(name,address,mobile,0.95) #95折
print("份数:{}费用:{}".format(servings,c2.cacl_all(servings)))
类的组合使用
#类的组合使用
class Food2(object):
"""
食物类
属性:品名、折扣、单价、份数
"""
def __init__(self,name,discount,price,servings):
self.name = name
self.discount = discount
self.price = price
self.servings = servings
class Customers(object):
"""
顾客类
属性:姓名、地址、手机号
"""
def __init__(self,name,adress,mobile):
self.name = name
self.adress = adress
self.mobile = mobile
#订购食物方法
def order_food(self,fname,servings,fprice,discount):
return Food2(fname,servings,fprice,discount)
#计算顾客总费用方法
def cacl_all(self,flist): #flist 为顾客订单
money = 0
for dd in flist:
money += dd.price*dd.servings*dd.discount
return money
if __name__ == '__main__':
#顾客1
name = input("欢迎光临Junying饺子馆!您好,您的名字:")
mobile = input("请问您的手机号:")
adress = input("请问您的地址:")
c1 = Customers(name,mobile,adress)
flist = []
while True:
fname = input("请问您需要什么:")
servings = int(input("请问您的份数:"))
price = eval(input("价格:"))
discount = eval(input("折扣:"))
flist.append(c1.order_food(fname,servings,price,discount)) #加入订单
answer = input("您还需要吗?(y/n)")
if answer != 'y' and answer != 'Y':
break
print("感谢您的惠顾!")
print("您的总费用是%f"%(c1.cacl_all(flist))) #调用方法算出总金额