IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Python知识库 -> 43.Python对象属性查找&绑定方法 -> 正文阅读

[Python知识库]43.Python对象属性查找&绑定方法

1.属性查找顺序

1.1.对象属性查找

当对象创建独有的属性,与类中的属性一致.
属性的查找:先从自己的对象中查找,然后在去产生对象的类中取找.
class Student():
    school = 'x1'

    def __init__(self):
        pass


# 对象查找
stu1 = Student()
stu2 = Student()
print(stu1.school)  # x1
print(stu2.school)  # x1

# 对象查找
stu1.school = 'x2'
print(stu1.school)  # x2
print(stu2.school)  # x1

1.2类查找

在类中定义的属性是类属性.
类名.属性查看属性的值.
类无法查找到对象的属性.
class Student():
    # 定义一个属性
    school = 'x1'

    def __init__(self, name):
        self.name = name


stu = Student('kid')
print(Student.school)  # x1

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))  # kid成功选择python课程!


# 实例化
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))  # kid成功选择python课程!

        
# 类调用对象
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)  # x2 查

Student.xx = 'x3'  # 改
print(Student.xx)  # x3 查

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


# 继承 a q w e r
class Galen(Skill):
    pass  # 被动技能


# 继承 a q w e r
class RuiWen(Skill):
    pass  # 被动技能


s1 = Galen(50, 100, 80, 400, 600, 1300)
s2 = RuiWen(60, 112, 50, 300, 650, 1250)

# 打到血为0
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 装饰器 将方法绑定给类
    @classmethod
    def config(cls):
        obj = cls(IP, PORT)
        return obj

# 类调用方法
obj = Mysql.config()
print(obj.ip)

image-20211203214940191

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__)  # {'__name': 'kid'}

7.5方法变形

方式名同样可以使用__进行变形.
class Test():

    def __index(self):
        print('hello word!')

    def get_index(self):
        return self.__class__.__index(self)


s1 = Test()
s1.get_index()  # hello word!

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变形
    __name = 0

    # 使用property 假装成name
    @property
    def name(self):
        return self.__class__.__name


s1 = Test()
print(s1.name)  # 0

8.2自动触发

@函数名.setter  修改值时自动触发
@函数名.deleter 删除值时自动触发
1.类属性
class Test():
    # 真正的name变形
    __name = 0

    # 使用property 假装成name
    @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 假装成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
不能删除!
"""
  Python知识库 最新文章
Python中String模块
【Python】 14-CVS文件操作
python的panda库读写文件
使用Nordic的nrf52840实现蓝牙DFU过程
【Python学习记录】numpy数组用法整理
Python学习笔记
python字符串和列表
python如何从txt文件中解析出有效的数据
Python编程从入门到实践自学/3.1-3.2
python变量
上一篇文章      下一篇文章      查看所有文章
加:2021-12-05 12:00:09  更:2021-12-05 12:00:45 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/16 3:48:29-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码