文章详情

短信预约-IT技能 免费直播动态提醒

请输入下面的图形验证码

提交验证

短信预约提醒成功

python3--面向对象的进阶

2023-01-30 21:59

关注

昨日内容练习

class A:
    def func1(self):pass  # func1 普通方法
    @classmethod
    def func2(self):pass  # func2 类方法
    @staticmethod
    def func3(self):pass  # func3 静态方法

# func1 普通方法 对象和类绑定的过程
a = A()
b = A()
print(A.func1)  # 3个地址都不一样
print(a.func1)
print(b.func1)

# func2 类方法 由于不适用对象内存空间中的属性,
# 所以不会将对象和方法绑在一起,而是将类和方法绑在一起
print(A.func2)
print(a.func2)  # 对象能找到类,类里面绑着方法
print(b.func2)

# func3 静态方法 不是绑定方法 没有和对象或者类发生任何绑定关系
print(A.func3)
print(a.func3)
print(b.func3)

执行结果

1 普通方法,func1结果


<bound method A.func1 of

<bound method A.func1 of


2 类方法,func2结果

<bound method A.func2 of

<bound method A.func2 of

<bound method A.func2 of


3 静态方法,func3结果





isinstance(对象名,类名) 返回True,False

isinstance(obj,cls)检查obj是否是类cls的对象

例子

class A:pass
class B(A):pass
b = B()
print(isinstance(b, A))  # 能够检测到继承关系
print(isinstance(b, B))
print(type(b) is A)
print(type(b) is B)  # type只单纯的判断类

执行结果

True

True

False

True


issubclass(子类名,父类名) 返回True,False

issubclass(sub,super)检查sub类是否是super类的派生类

例子,单继承

class A:pass
class B:pass
class C(B):pass
class D(C):pass
print(issubclass(C,B))  # 判断C是不是B的子类
print(issubclass(D,C))  # 判断D是不是C的子类
print(issubclass(D,B))  # 判断D是不是C的子类
print(issubclass(D,A))  # 判断D是不是A的子类

执行结果

True

True

True

False


例子2,多继承

class A:pass
class B:pass
class C(A,B):pass
class D(C):pass

print(issubclass(C,A))  # 判断C是不是A的子类
print(issubclass(C,B))  # 判断C是不是B的子类
print(issubclass(D,B))  # 判断D是不是B的子类
print(issubclass(D,A))  # 判断D是不是A的子类

执行结果

True

True

True

True


面向对象进阶(反射,非常重要的知识点*******7星)

1 什么是反射

反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问,检测和修改它本身状态或行为的一种能力(自省),它首先被程序语言的设计领域所采用,并在Lisp和面向对象取得了成绩


2 python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)

四个可以实现自省的函数

下列方法适用于类和对象(一切皆对象,类本身也是一个对象)


反射

正常情况下如果可以拿到这个变量, 那么如有这个变量的字符串形式,就是用反射可以获取到这个值

使用字符串数据类型的变量名 访问一个命名空间中的名字

找一个属性,直接就可以找到这个属性的值

找一个方法,找到的是这个方法的内存地址


getattr 使用字符串数据类型的变量名 访问一个命名空间中的名字

源代码

def getattr(object, name, default=None): # known special case of getattr
    """
    getattr(object, name[, default]) -> value
    
    Get a named attribute from an object; getattr(x, 'y') is equivalent to x.y.
    When a default argument is given, it is returned when the attribute doesn't
    exist; without it, an exception is raised in that case.
    """
    pass


例子

class A:
    role = 'person'  # 静态属性
    def func(self):
        print('*'*10)
print(A.__dict__['role'])  # 查看静态属性的值
ret = input('>>>')  # 用户输入role
print(A.__dict__[ret])  # 实际上就是执行了最上面的print

执行结果

person

>>>role

person


那么如何让用户输入func然后去执行类里面的方法func呢?

class A:
    role = 'person'  # 静态属性
    def func(self):
        print('*'*10)
ret = input('>>>')  # 用户输入func
# 这里要用到字符串拼接+eval函数才能实现
s = 'A'
ss = s + '.' + ret
eval(ss)(1)

执行结果

>>>func

**********


这样很麻烦,也不安全,还有什么方法呢?

getattr()  从命名空间中获取这个名字对应的值

class A:
    role = 'person'  # 静态属性
    def func(self):
        print('*'*10)

# 从A的命名空间里找一个属性,直接就可以找到这个属性的值
# 通俗点就是需要获取谁(func),就是getattr(A,'func') getattr(类,'属性名')
print(getattr(A, 'role'))

a = A()  # 实例化一个对象a
# 从A的命名空间里面找一个方法,找到的是这个方法的内存地址,如果要执行这个方法,在后面加()
print(getattr(a, 'func'))
getattr(a, 'func')()

#getattr如何让用户输入一个类中的方法名,并执行
ret = input('>>>:')
getattr(a, ret)()  # getattr(a, ret)实际上获取的就是func方法的内存地址,后面加()就表示执行

执行结果

person

<bound method A.func of

**********

>>>:func

**********


例2

class A:
    role = 'Person'
    def __init__(self):
        self.money = 500
    def func(self):
        print('*'*10)
a = A()
print(a.func)  # 打印a.func的内存地址
getattr(a, 'func')()  # 使用getattr获取名字对应的值,名字加()就表示执行这个方法
print(getattr(a, 'money'))  # 使用getattr获取名字对应的值

执行结果

<bound method A.func of

**********

500



hasattr() 判断一个命名空间中有没有这个名字

源码

def hasattr(*args, **kwargs): # real signature unknown
    """
    Return whether the object has an attribute with the given name.
    
    This is done by calling getattr(obj, name) and catching AttributeError.
    """
    pass


例1

class A:
    role = 'person'
    def func(self):
        print('py3study.com')

a = A()
print(hasattr(a, 'r'))  # 也可以写成 print(hasattr(A, 'r'))
print(hasattr(a, 'role'))
print(hasattr(a, 'func'))

执行结果

False

True

True


hasattr()经常与getattr()一起用,首先判断一个命名空间中有没有这个名字,有的话就用getattr获取这个名字对应的值

示例

class A:
    role = 'person'
    def func(self):
        print('py3study.com')

ret = input('>>>')
if hasattr(A, ret):  # 判断是否存在
    print(getattr(A, ret))  # 如果存在则打印内存地址
if hasattr(A, ret):
    func = getattr(A, ret)  # 如果存在则执行这个方法
    func(1)
else:
    print('error')  # 不存在则报错

执行结果

>>>func


py3study.com


类使用类命名空间中的名字

对象使用对象能用的方法和属性

模块使用模块中的名字

导入os模块,利用getattr获取os模块中'rename'对应的值,os.rename('old','new')执行改文件名的操作

import os;getattr(os, 'rename')('user', 'user_info') 


导入time模块,利用getattr获取time模块中'time'对应的值,print(time.time())打印时间戳

import time;print(getattr(time, 'time')())


从自己所在的模块中使用自己名字

示例

def login():
    print('执行login功能')

def  register():
    print('执行register功能')

import sys
print(sys.modules['__main__'])  # 打印当前文件的路径,一个.py文件就相当于一个模块
func = input('>>>')
if hasattr(sys.modules['__main__'], func):  # 判断当前模块中的命名空间,是否有用户输入的这个名字
    getattr(sys.modules['__main__'], func)()  # 存在的话执行用户输入的名字加()这个函数

执行结果

>>>login

执行login功能


类使用类命名空间中的名字

getattr(类名,'名字')

对象使用对象能用的方法和属性

getattr(对象名,'名字')

模块使用模块中的名字

导入模块

getattr(模块名,'名字')

从自己所在的模块中使用自己名字

import sys

getattr(sys.modules['__main__'],名字)

getattr一定要和hasattr配合使用


反射 :4个内置函数

getattr  # 从命名空间中获取这个名字对应的值

hasattr  # 判断一个命名空间中有没有这个名字  

setattr  # 修改和新建

delattr  # 删除一个属性


setattr,delattr

setattr源码

def setattr(x, y, v): # real signature unknown; restored from __doc__
    """
    Sets the named attribute on the given object to the specified value.
    
    setattr(x, 'y', v) is equivalent to ``x.y = v''
    """
    pass

delattr源码

def delattr(x, y): # real signature unknown; restored from __doc__
    """
    Deletes the named attribute from the given object.
    
    delattr(x, 'y') is equivalent to ``del x.y''
    """
    pass



增删改 对象属性

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

    def wahaha(self):
        print('噢噢噢噢哦哦哦')
a = A('Sam')
print(a.name)
a.wahaha()
print(a.__dict__)

# 使用setattr: 无则增加有则修改的原则
setattr(a, 'age', 18)  # 给a对象新增一个属性
print(a.__dict__)
a.wahaha()  # 执行wahaha()方法

# 使用setattr: 无则增加有则修改的原则
setattr(a, 'name', 'Jack')  # 修改a对象的name属性为Jack
print(a.__dict__)

del a.name  # 删除a对象的name属性
print(a.__dict__)

# 使用delattr删除
delattr(a, 'age')
print(a.__dict__)

执行结果

Sam

噢噢噢噢哦哦哦

{'name': 'Sam'}

{'name': 'Sam', 'age': 18}

噢噢噢噢哦哦哦

{'name': 'Jack', 'age': 18}

{'age': 18}

{}


例2

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

    def  wahaha(self):
        print('aaaaaaaaaaa')

def qqxing(self):
    print('qqqqqqqqq')

a = A('Tom')
setattr(a, 'qqxing', qqxing)  # setattr把函数qqxing 加到类里面去了
a.qqxing(a)

# 使用getattr函数从命名空间中获取这个名字对应的值
getattr(a, 'qqxing')(a)

执行结果

qqqqqqqqq

qqqqqqqqq


阅读原文内容投诉

免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

软考中级精品资料免费领

  • 历年真题答案解析
  • 备考技巧名师总结
  • 高频考点精准押题
  • 2024年上半年信息系统项目管理师第二批次真题及答案解析(完整版)

    难度     813人已做
    查看
  • 【考后总结】2024年5月26日信息系统项目管理师第2批次考情分析

    难度     354人已做
    查看
  • 【考后总结】2024年5月25日信息系统项目管理师第1批次考情分析

    难度     318人已做
    查看
  • 2024年上半年软考高项第一、二批次真题考点汇总(完整版)

    难度     435人已做
    查看
  • 2024年上半年系统架构设计师考试综合知识真题

    难度     224人已做
    查看

相关文章

发现更多好内容

猜你喜欢

AI推送时光机
位置:首页-资讯-后端开发
咦!没有更多了?去看看其它编程学习网 内容吧
首页课程
资料下载
问答资讯