1.属性查找顺序
1.1.对象属性查找
当对象创建独有的属性,与类中的属性一致.
属性的查找:先从自己的对象中查找,然后在去产生对象的类中取找.
class Student():
school = 'x1'
def __init__(self):
pass
stu1 = Student()
stu2 = Student()
print(stu1.school)
print(stu2.school)
stu1.school = 'x2'
print(stu1.school)
print(stu2.school)
1.2类查找
在类中定义的属性是类属性.
类名.属性查看属性的值.
类无法查找到对象的属性.
class Student():
school = 'x1'
def __init__(self, name):
self.name = name
stu = Student('kid')
print(Student.school)
2.使用方法
2.1对象使用
类中定义的方法是为了给对象使用的,
对象调用方法会将自己作为第一个参数传递给方法.
(Python提供的快捷方式)
class Student:
school = 'xxx'
def __init__(self, name, courses):
self.name = name
self.courses = courses
def elective(self, courses):
self.courses.append(courses)
print('%s成功选择%s课程!' % (self.name, courses))
stu1 = Student('kid', [])
stu1.elective('Python')
2.2类使用方法
类使用方法,不支持快捷方式,需要手动将对象作为第一个参数进行传递.
不推荐使用类去掉用方法.类中定义的方法是为了给对象使用的!
class Student:
school = 'xxx'
def __init__(self, name, courses):
self.name = name
self.courses = courses
def elective(self, courses):
self.courses.append(courses)
print('%s成功选择%s课程!' % (self.name, courses))
stu2 = Student('qq', [])
Student.elective(stu2, 'Linux')
3修改类的属性
3.1类增查改删
class Student:
school = 'x1'
def __init__(self, name, courses):
self.name = name
self.courses = courses
print(Student.school)
Student.xx = 'x2'
print(Student.xx)
Student.xx = 'x3'
print(Student.xx)
del Student.xx
print(Student.__dict__)
"""
{'__module__': '__main__', 'school': 'x1', '__init__': <function Student.__init__ at 0x00000218D0FBED08>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}
"""
3.2在方法内修改类的属性
在对象中使用__class__的到类名,
类点属性得拿到值就可以进行修改.
class Student:
school = 'x1'
def __init__(self, name):
self.__class__.school = name
print(Student.__dict__)
stu1 = Student('x2')
print(Student.__dict__)
"""
'school': 'x1', ---
'school': 'x2', ---
"""
3.4练习1
题目:
1.定义一个类
2.产生一堆对象
3.统计生产多少个对象
class Count():
num = 0
def __init__(self):
self.__class__.num += 1
s1 = Count()
s2 = Count()
s3 = Count()
s4 = Count()
print(Count.num)
3.5练习2
import random
import time
class Skill():
def __init__(self, a, q, w, e, r, hp):
self.a = a
self.q = q
self.w = w
self.e = e
self.r = r
self.hp = hp
class Galen(Skill):
pass
class RuiWen(Skill):
pass
s1 = Galen(50, 100, 80, 400, 600, 1300)
s2 = RuiWen(60, 112, 50, 300, 650, 1250)
while True:
print('德玛hp:%s 锐雯hp:%s' % (s1.hp, s2.hp))
Galen_Skill_pool = [s1.a, s1.q, s1.w, s1.e, s1.r]
Galen_Moves = random.choice(Galen_Skill_pool)
Skill_pool = ['a', 'q', 'w', 'e', 'r']
Skill_index = Galen_Skill_pool.index(Galen_Moves)
print('盖伦使用 %s 技能 使瑞雯掉血 %s ' % (Skill_pool[Skill_index], Galen_Moves))
s2.hp -= Galen_Moves
print('德玛hp:%s 锐雯hp:%s' % (s1.hp, s2.hp))
RuiWen_Skill_pool = [s2.a, s2.q, s2.w, s2.e, s2.r]
RuiWen_Moves = random.choice(RuiWen_Skill_pool)
Skill_index = Galen_Skill_pool.index(Galen_Moves)
print('瑞雯使用 %s 技能 使盖伦掉血 %s ' % (Skill_pool[Skill_index], RuiWen_Moves))
s1.hp -= RuiWen_Moves
time.sleep(1)
if s1.hp < 0 or s2.hp < 0:
print('德玛hp:%s 锐雯hp:%s' % (s1.hp, s2.hp))
if s1.hp < 0:
print('德玛死了')
else:
print('锐雯死了')
break
4.绑定方法
绑定方法: 绑定给谁就是将谁作为第一个参数传给方法.
4.1绑定给对象
将对象作为第一个参数,传递给方法.
方法是为对象提供的,默认就是绑定给对象.
对象能直接使用.的方式来调用方法.
类使用方法不提供自动将对象作为第一个参数,传递给方法.
需要手动正常的传入值。
class Mysql():
country = 'xxx'
def __init__(self, ip, port):
self.ip = ip
self.port = port
def tell_info(self):
print('%s : %s' % (self.ip, self.port))
obj1 = Mysql('127.0.0.1', 80)
obj1.tell_info()
print(obj1.country)
obj2 = Mysql('127.0.0.1', 80)
obj2.tell_info()
print(obj2.country)
4.2绑定给类
为什么要绑定给类?
上面的代码如果需要产生多个对象,而参数又是一样的,且不会变的.
则可以将相同的参数写进配置文件中.在使用类绑定方法的方式,自定传递参数.
类最为参数传递时,方法中使用cls做为参数名.
IP = '127.0.0.1'
PORT = 81
class Mysql():
def __init__(self, ip, port):
self.ip = ip
self.port = port
@classmethod
def config(cls):
obj = cls(IP, PORT)
return obj
obj = Mysql.config()
print(obj.ip)
4.3练习
登入验证
class InData():
def __init__(self, name, pwd):
self.name = name
self.pwd = pwd
@classmethod
def file(cls):
name = 'kid'
pwd = '123'
obj = cls(name, pwd)
return obj
def test(self, in_name, in_pwd):
is_verify = True
if not self.name == in_name:
is_verify = False
if not self.pwd == in_pwd:
is_verify = False
if is_verify:
return '登入成功'
return '用户或密码错误'
obj = InData.file()
print(obj.test(input('输入用户名称>>>:'), input('输入用户密码>>>:')))
5.类与类型的概念/一切皆对象
类与类型的概念
Python3中统一了类与类型的概念。
l = [1, 2, 3] 等同 l = list(1, 2 ,3)
print(type(l))
<clsaa 'list'>
l1 .append(4) ---> 将l1传入append() 中
对象调用方法将自己作为第一个参数传递。
list是类,类调用方法,方法绑定给类
l = [1, 2, 3]
list.append(l, 4)
print(l) [1, 2, 3, 4]
print(isinstance(l1, list)) # True 判断某个值是否由某个类创建
class AAA():
pass
aaa = AAA()
print(isinstance(aaa, AAA)) # True 判断某个值是否由某个类创建
Python中所有的数据都是通过调用类实例化得来.
一切皆对象
6.非绑定方法(静态方法)
非绑定方法:不绑定对象也不绑定类.定义在类中,调用时传递对象和类名,
其他的参数该怎么传入就怎么传入.
@staticmethod # 静态方法语法糖
6.1不带参数
class Mysql():
pass
@staticmethod
def create_id():
"""
添加装饰器后 self 删除
不需要参数
"""
import uuid
print(uuid.uuid4())
obj = Mysql()
obj.create_id()
Mysql().create_id()
6.2带参数
需要参数就正常传递.
class Mysql():
pass
@staticmethod
def create_id(x):
import uuid
print(x)
print(uuid.uuid4())
obj = Mysql()
obj.create_id(1)
Mysql.create_id(1)
7.隐藏属性
7.1目的
隐藏属性的目的:隐藏属性,不然外界直接使用.对数据的增删改查封装成一个个接口,在接口中设置限制.
7.2变形
在名称的前面加上__,对名称做变形处理,只在定义阶段做变形.
__名称 变形 --> _类名__名称
1.定义阶段,只是语法上的变形,还有可以按_类名__名称的方式取值.
2.隐藏只对外不对内,如果在返回类中的属性,在类中设置对外的接口.
3.变形操作只在定义阶段,之后所有属性都不会变形.
class Test():
__name = 10
print(Test.__name)
"""
AttributeError: type object 'Test' has no attribute '__name'
属性错误: 类型对象“Test”没有属性“__name”
"""
class Test():
__name = 10
print(Test.__dict__)
"""
'_Test__name': 10,
"""
7.3在类中访问变形属性
在定义阶段两个__name都会变形为_Test__name' 所有能访问得到.
class Test():
__name = 10
@classmethod
def get_name(cls):
return cls.__name
print(Test.get_name())
7.4不在类中定义
不在类中定义,__不会有隐藏功能
class Test():
pass
s1 = Test()
s1.__name = 'kid'
print(s1.__dict__)
7.5方法变形
方式名同样可以使用__进行变形.
class Test():
def __index(self):
print('hello word!')
def get_index(self):
return self.__class__.__index(self)
s1 = Test()
s1.get_index()
7.6使用场景
对数据进行变形处理,隐藏访问,做一个对外开发的接口,
在接口函数中限制数据值的增删改查操作.
class Test():
__name = 0
def set_num(self, x):
if isinstance(x, int):
self.__class__.__name = x
return self.__class__.__name
return '输入不是int类型数据!'
s1 = Test()
print(s1.set_num(1))
"""
输入1 显示 1
输入'o' 显示 不是int类型数据!
"""
8.property装饰器
property装饰器将一个方法伪装成一个属性,
看起来像是在使用方法,其实是在使用方法.
有两个额外的装饰器搭配一起使用.
格式:
@property
def 函数():
pass
@函数名.setter 修改值时自动触发
@函数名.deleter 删除值时自动触发
8.1使用
property装饰器配送隐藏属性一起使用.
将真正的属于进行变形处理到达隐藏的效果.
定义一个接口函数,这个函数的名字要是没隐藏前的属性名.
class Test():
__name = 0
@property
def name(self):
return self.__class__.__name
s1 = Test()
print(s1.name)
8.2自动触发
@函数名.setter 修改值时自动触发
@函数名.deleter 删除值时自动触发
1.类属性
class Test():
__name = 0
@property
def name(self):
return self.__class__.__name
@name.setter
def name(self, x):
if isinstance(x, int):
self.__class__.__name = x
else:
print('输入不是int类型')
@name.deleter
def name(self):
print('不能删除!')
s1 = Test()
print(s1.name)
s1.name = 12
print(s1.name)
del s1.name
2.对象属性
class Test():
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, x):
if isinstance(x, str):
self.__name = x
else:
print('输入字符串')
@name.deleter
def name(self):
print('不能删除!')
s1 = Test('kid')
print(s1.name)
s1.name = 'qz'
print(s1.name)
del s1.name
"""
kid
qz
不能删除!
"""
8.3.另一种格式
按 伪装属性 修改属性 删除属性 排序
名字 = property(get_name, set_name, del_name)
class Test():
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_name(self, x):
if isinstance(x, str):
self.__name = x
else:
print('输入字符串')
def del_name(self):
print('不能删除!')
name = property(get_name, set_name, del_name)
s1 = Test('kid')
print(s1.name)
s1.name = 'qz'
print(s1.name)
del s1.name
"""
kid
qz
不能删除!
"""
|