京公网安备 11010802034615号
经营许可证编号:京B2-20210330
python进阶_浅谈面向对象进阶
学了面向对象三大特性继承,多态,封装。今天我们看看面向对象的一些进阶内容,反射和一些类的内置函数。
一、isinstance和issubclass
class Foo:
pass
class Son(Foo):
pass
s = Son()
#判断一个对象是不是这个类的对象,传两个参数(对象,类)
print(isinstance(s,Son))
print(isinstance(s,Foo))
#type更精准
print(type(s) is Son)
print(type(s) is Foo)
#判断一个类是不是另一类的子类,传两个参数(子类,父类)
print(issubclass(Son,Foo))
print(issubclass(Son,object))
print(issubclass(Foo,object))
print(issubclass(int,object))
二、反射
反射的概念是由Smith在1982年首次提出的,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力(自省)。这一概念的提出很快引发了计算机科学领域关于应用反射性的研究。它首先被程序语言的设计领域所采用,并在Lisp和面向对象方面取得了成绩。
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
四个可以实现反射的函数:hasattr,getattr,setattr,delattr
下列方法适用于类和对象(一切皆对象,类本身也是一个对象)
class Foo:
def __init__(self):
self.name = 'egon'
self.age = 73
def func(self):
print(123)
egg = Foo()
#常用:
#hasattr
#getattr
# print(hasattr(egg,'name'))
print(getattr(egg,'name'))
if hasattr(egg,'func'): #返回bool
Foo_func = getattr(egg,'func') #如果存在这个方法或者属性,就返回属性值或者方法的内存地址
#如果不存在,报错,因此要配合hasattr使用
Foo_func()
#不常用:
#setattr
# setattr(egg,'sex','属性值')
# print(egg.sex)
# def show_name(self):
# print(self.name + ' sb')
# setattr(egg,'sh_name',show_name)
# egg.sh_name(egg)
# show_name(egg)
# egg.sh_name()
#delattr
# delattr(egg,'name')
# print(egg.name)
# print(egg.name)
# egg.func()
# print(egg.__dict__)
#反射
#可以用字符串的方式去访问对象的属性、调用对象的方法
反射举例1
class Foo:
f = 123 #类变量
@classmethod
def class_method_demo(cls):
print('class_method_demo')
@staticmethod
def static_method_demo():
print('static_method_demo')
# if hasattr(Foo,'f'):
# print(getattr(Foo,'f'))
print(hasattr(Foo,'class_method_demo'))
method = getattr(Foo,'class_method_demo')
method()
print(hasattr(Foo,'static_method_demo'))
method2 = getattr(Foo,'static_method_demo')
method2()
#类也是对象
反射举例2
import my_module
# print(hasattr(my_module,'test'))
# # func_test = getattr(my_module,'test')
# # func_test()
# getattr(my_module,'test')()
#import其他模块应用反射
from my_module import test
def demo1():
print('demo1')
import sys
print(__name__) #'__main__'
print(sys.modules)
#'__main__': <module '__main__' from 'D:/Python代码文件存放目录/S6/day26/6反射3.py'>
module_obj =sys.modules[__name__] #sys.modules['__main__']
# module_obj : <module '__main__' from 'D:/Python代码文件存放目录/S6/day26/6反射3.py'>
print(module_obj)
print(hasattr(module_obj,'demo1'))
getattr(module_obj,'demo1')()
#在本模块中应用反射
反射举例3
#对象
#类
#模块 : 本模块和导入的模块
def register():
print('register')
def login():
pass
def show_shoppinglst():
pass
#
print('注册,登录')
ret = input('欢迎,请输入您要做的操作: ')
import sys
print(sys.modules)
# my_module = sys.modules[__name__]
# if hasattr(my_module,ret):
# getattr(my_module,ret)()
if ret == '注册':
register()
elif ret == '登录':
login()
elif ret == 'shopping':
show_shoppinglst()
反射举例4
def test():
print('test')
三、类的内置函数
1、__str__和__repr__
class Foo:
def __init__(self,name):
self.name = name
def __str__(self):
return '%s obj info in str'%self.name
def __repr__(self):
return 'obj info in repr'
f = Foo('egon')
# print(f)
print('%s'%f)
print('%r'%f)
print(repr(f)) # f.__repr__()
print(str(f))
#当打印一个对象的时候,如果实现了str,打印中的返回值
#当str没有被实现的时候,就会调用repr方法
#但是当你用字符串格式化的时候 %s和%r会分别去调用__str__和__repr__
#不管是在字符串格式化的时候还是在打印对象的时候,repr方法都可以作为str方法的替补
#但反之不行
#用于友好的表示对象。如果str和repr方法你只能实现一个:先实现repr
2、__del__
class Foo:
def __del__(self):
print('执行我啦')
f = Foo()
print(123)
print(123)
print(123)
#析构方法,当对象在内存中被释放时,自动触发执行。
#注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。
3、item系列
__getitem__\__setitem__\__delitem__
class Foo:
def __init__(self):
self.name = 'egon'
self.age = 73
def __getitem__(self, item):
return self.__dict__[item]
def __setitem__(self, key, value):
# print(key,value)
self.__dict__[key] = value
def __delitem__(self, key):
del self.__dict__[key]
f = Foo()
print(f['name'])
print(f['age'])
f['name'] = 'alex'
# del f['name']
print(f.name)
f1 = Foo()
print(f == f1)
4、__new__
# class A:
# def __init__(self): #有一个方法在帮你创造self
# print('in init function')
# self.x = 1
#
# def __new__(cls, *args, **kwargs):
# print('in new function')
# return object.__new__(A, *args, **kwargs)
# a = A()
# b = A()
# c = A()
# d = A()
# print(a,b,c,d)
#单例模式
class Singleton:
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
cls._instance = object.__new__(cls, *args, **kw)
return cls._instance
one = Singleton()
two = Singleton()
three = Singleton()
go = Singleton()
print(one,two)
one.name = 'alex'
print(two.name)
5、__call__
class Foo:
def __init__(self):
pass
def __call__(self, *args, **kwargs):
print('__call__')
obj = Foo() # 执行 __init__
obj() # 执行 __call__
Foo()() # 执行 __init__和执行 __call__
#构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()
6、__len__,__hash__
class Foo:
def __len__(self):
return len(self.__dict__)
def __hash__(self):
print('my hash func')
return hash(self.name)
f = Foo()
print(len(f))
f.name = 'egon'
print(len(f))
print(hash(f))
7、__eq__
class A:
def __init__(self):
self.a = 1
self.b = 2
def __eq__(self,obj):
if self.a == obj.a and self.b == obj.b:
return True
a = A()
b = A()
print(a == b)
#__eq__控制着==的结果
8、内置函数实例
class FranchDeck:
ranks = [str(n) for n in range(2,11)] + list('JQKA')
suits = ['红心','方板','梅花','黑桃']
def __init__(self):
self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
for suit in FranchDeck.suits]
def __len__(self):
return len(self._cards)
def __getitem__(self, item):
return self._cards[item]
deck = FranchDeck()
print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck))
纸牌游戏
class FranchDeck:
ranks = [str(n) for n in range(2,11)] + list('JQKA')
suits = ['红心','方板','梅花','黑桃']
def __init__(self):
self._cards = [Card(rank,suit) for rank in FranchDeck.ranks
for suit in FranchDeck.suits]
def __len__(self):
return len(self._cards)
def __getitem__(self, item):
return self._cards[item]
def __setitem__(self, key, value):
self._cards[key] = value
deck = FranchDeck()
print(deck[0])
from random import choice
print(choice(deck))
print(choice(deck))
from random import shuffle
shuffle(deck)
print(deck[:5])
纸牌游戏2
class Person:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
def __hash__(self):
return hash(self.name+self.sex)
def __eq__(self, other):
if self.name == other.name and other.sex == other.sex:return True
p_lst = []
for i in range(84):
p_lst.append(Person('egon',i,'male'))
print(p_lst)
print(set(p_lst))
#只要姓名和年龄相同就默认为一人去重
去重
以上这篇python进阶_浅谈面向对象进阶就是小编分享给大家的全部内容了,希望能给大家一个参考
数据分析咨询请扫描二维码
若不方便扫码,搜微信号:CDAshujufenxi
数字化经营时代,企业的市场竞争早已从经验决策转向数据决策。门店营收、用户转化、产品销量、成本损耗、存量资产等所有经营行为 ...
2026-05-22在MySQL数据库日常运维、业务数据校验、数据迁移与数据清洗场景中,自增主键ID的连续性校验是一项基础且关键的工作。MySQL的Auto ...
2026-05-22 很多企业团队并非缺乏指标,而是陷入“指标失控”:仪表盘上堆满实时跳动的数据,却无法回答“当前瓶颈在哪、下一步该做什么 ...
2026-05-22【核心关键词】大数据、可视化、存储、架构、客户、离线、产品、同步、实时、数据仓库、数据分析、数据可视化、存储数据、离线 ...
2026-05-21在电商流量红利消退、公域获客成本持续走高的当下,存量用户深度挖掘已成为店铺增收增效的核心抓手。相较于付费投放获取的陌生新 ...
2026-05-21 很多数据分析师每天盯着几十个指标,但当被问到“这套指标要支撑什么业务目标”“指标之间是什么逻辑关系”“业务变化时如何 ...
2026-05-21在数据驱动决策的时代,数据质量直接决定分析结果的可靠性与准确性,而异常值作为数据清洗中的核心痛点,往往会扭曲分析结论、误 ...
2026-05-20 很多数据分析师每天盯着GMV、DAU、转化率,但当被问到“哪些指标在所有行业都适用”“哪些指标只对电商有意义”“二者如何搭 ...
2026-05-20Agent的能力边界,很大程度上取决于其掌握的Skill质量和数量。传统做法是靠人工编写和维护Skill,但这条路很快会遇到瓶颈。业务 ...
2026-05-20在统计分析中,方差分析(ANOVA)是一种常用的假设检验方法,核心用于分析“一个或多个自变量对单个因变量的影响”,广泛应用于 ...
2026-05-19 很多数据分析师每天盯着GMV、DAU、转化率,但当被问到“什么是指标”“指标和维度有什么区别”“如何定义指标值的计算规则和 ...
2026-05-19想高效备考 CDA 一级,拒绝盲目刷题、冗余学习?《CDA 一级教材知识手册》重磅来袭!以官方教材为核心,浓缩 13 章 103 个核心考 ...
2026-05-19在数据统计分析中,卡方检验是一种常用的非参数检验方法,核心用于判断两个或多个分类变量之间是否存在显著关联,广泛应用于市场 ...
2026-05-18在企业数字化转型的浪潮中,很多企业陷入了“技术堆砌”的误区——上线了ERP、CRM、BI等各类系统,积累了海量数据,却依然面临“ ...
2026-05-18小陈是某电商平台的数据分析师。老板交给他一个任务:“我们平台的注册用户已经突破1000万了,想了解一下用户的平均月消费金额。 ...
2026-05-18【专访摘要】本次CDA持证专访邀请到拥有丰富物流供应链数据分析经验的赖尧,他结合自身在京东、华莱士、兰格赛等企业的从业经历 ...
2026-05-15在数字化时代,企业的每一次业务优化、每一项技术迭代,都需要回答一个核心问题:这个动作到底能带来多少价值?是提升了用户转化 ...
2026-05-15在数据仓库建设中,事实表与维度表是两大核心组件,二者相互关联、缺一不可,共同构成数据仓库的基础架构。事实表聚焦“发生了什 ...
2026-05-15 很多数据分析师沉迷于复杂的机器学习算法,却忽略了数据分析最基础也最核心的能力——描述性统计。事实上,80%的商业分析问 ...
2026-05-15【核心关键词】互联网、机会、运营、关键词、账户、数字化、后台、客户、成本、网络、数据分析、底层逻辑、市场推广、数据反馈 ...
2026-05-14