day27 反射、内置方法

时间:2022-01-27 20:34:20

一、isinstance和issubclass

class Foo:
pass

class Son(Foo):
pass

s
= Son()
#判断一个对象是不是这个类的对象,传两个参数(对象,类)
#
print(isinstance(s,Son))
#
print(isinstance(s,Foo))
#
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))

 

二、反射

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

四个方法:hasattr(),getattr(),setattr(),delattr()

1.对象中

 

__author__ = 'ctz'
class Foo:
def __init__(self,name,age):
self.name
=name
self.age
=age

def fun(self):
print("...........ctz")

f
=Foo("ctz",21)
print(hasattr(f,"name"))
print(hasattr(f,"age"))
print(hasattr(f,"fun"))
print(getattr(f,"name"))
print(getattr(f,"age"))
print(getattr(f,"fun"))
fu
=getattr(f,"fun")
fu()



print("".center(50,"-"))

setattr(f,
"name","egon")
setattr(f,
"age",73)

print(f.name,f.age)

print("--------------------")

delattr(f,
"name")
print(f.name)

 

True
True
True
ctz
21
<bound method Foo.fun of <__main__.Foo object at 0x00000000023F9DD8>>
...........ctz
--------------------------------------------------
egon
73
--------------------
Traceback (most recent call last):
File
"G:/test/week6/day27/反射1 对象.py", line 32, in <module>
print(f.name)
AttributeError:
'Foo' object has no attribute 'name'

 

 

2.类中

__author__ = 'Administrator'
class Foo:
f
=123
@staticmethod
def static():
print("static......")

@classmethod
def clas(cls):
print(cls.f,"class.............")


print(hasattr(Foo,"f"))
print(hasattr(Foo,"static"))
print(hasattr(Foo,"clas"))


if hasattr(Foo,"f"):
print(getattr(Foo,"f"))

print(getattr(Foo,"static"))
print(getattr(Foo,"clas"))
s
=getattr(Foo,"static")
s()
c
=getattr(Foo,"clas")
c()
True
True
True
123
<function Foo.static at 0x000000000241B9D8>
<bound method Foo.clas of <class '__main__.Foo'>>
static......
123 class.............

3.模块

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')()
#在本模块中应用反射
__author__ = 'Administrator'
import aa

print(hasattr(aa,"bb"))
g
=getattr(aa,"bb")
g()

def Demo():
print("本模块自己的反射")

import sys
print(sys.modules)
module
=sys.modules[__name__]
if hasattr(module,"Demo"):
d
=getattr(module,"Demo")
d()
def bb():
print("bbbbb")
#aa

二、内置方法:

__str__和__repr__

改变对象的字符串显示__str__,__repr__

自定制格式化字符串__format__

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

__del__

析构方法,当对象在内存中被释放时,自动触发执行。

注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用是由解释器在进行垃圾回收时自动触发执行的。

__author__ = 'Administrator'
class Foo:
def __del__(self):
print("执行我来")

f
= Foo()
print(123)
print(123)
del f
print(123)
print(123)
print(123)

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()
# f['name'] = 'alex'
#
del f['name']
#
print(f.name)
f1 = Foo()
print(f == f1)
# print(f[0])
#
print(f[1])
#
print(f[2])

单例模式

class Singleton:
def __new__(cls, *args, **kw):
if not hasattr(cls, '_instance'):
orig
= super(Singleton, cls)
cls._instance
= orig.__new__(cls, *args, **kw)
return cls._instance

one
= Singleton()
two
= Singleton()

two.a
= 3
print(one.a)
# 3
#
one和two完全相同,可以用id(), ==, is检测
print(id(one))
# 29097904
print(id(two))
# 29097904
print(one == two)
# True
print(one is two)

单例模式

__call__

对象后面加括号,触发执行。

注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

class Foo:

def __init__(self):
pass

def __call__(self, *args, **kwargs):

print('__call__')


obj
= Foo() # 执行 __init__
obj() # 执行 __call__

__len__

class A:
def __init__(self):
self.a
= 1
self.b
= 2

def __len__(self):
return len(self.__dict__)
a
= A()
print(len(a))
# 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))

__hash__

class A:
def __init__(self):
self.a
= 1
self.b
= 2

def __hash__(self):
return hash(str(self.a)+str(self.b))
a
= A()
print(hash(a))

__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)

 

纸牌游戏

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))

纸牌游戏

纸牌游戏2

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 self.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))

一道面试题