视频1 视频21 视频41 视频61 视频文章1 视频文章21 视频文章41 视频文章61 推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37 推荐39 推荐41 推荐43 推荐45 推荐47 推荐49 关键词1 关键词101 关键词201 关键词301 关键词401 关键词501 关键词601 关键词701 关键词801 关键词901 关键词1001 关键词1101 关键词1201 关键词1301 关键词1401 关键词1501 关键词1601 关键词1701 关键词1801 关键词1901 视频扩展1 视频扩展6 视频扩展11 视频扩展16 文章1 文章201 文章401 文章601 文章801 文章1001 资讯1 资讯501 资讯1001 资讯1501 标签1 标签501 标签1001 关键词1 关键词501 关键词1001 关键词1501 专题2001
python面向对象进阶篇
2020-11-27 14:23:10 责编:小OO
文档


下面小编就为大家带来一篇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))

#只要姓名和年龄相同就默认为一人去重

下载本文
显示全文
专题