#昨日内容回顾
class Foo:
def __init__(self,name):
self.name = name
self.age = 18
class Son(Foo):
def __init__(self,name,money):
# Foo.__init__(self,name) #!!!
self.age = 20
self.money = money
#Foo.__init__(self, name) #!!!
son = Son('egon',500)
print(son.__dict__)
# 类的方法存在于类中,
# 对象数据存在于对象的空间中,体现就是self这个指针,
# 所以在对age这个变量的操作过程,
# 其实就是调用类中方法,来操作self所指对象空间中的数据,
class B:pass
class A(B):pass
a = A()
print(isinstance(a,A)) # True
print(isinstance(a,B)) # True,a是B的子类的实例,
print(type(a) is A) # True
print(type(a) is B) # False,仅仅是判断是不是完全同样的类型,
def isinstance(x, A_tuple): # real signature unknown; restored from __doc__
"""判断一个对象和一个类有没有血缘关系
Return whether an object is an instance of a class or of a subclass thereof.
"""
class B:pass
class C(B):pass
class D(C):pass
print(issubclass(C,D)) #False
print(issubclass(D,C)) #True
print(issubclass(B,C)) #False
print(issubclass(C,B)) #True
print(issubclass(D,B)) #True
def issubclass(x, A_tuple): # real signature unknown; restored from __doc__
"""issubclass(子类名,父类名) 如果返回True,说明有继承关系
Return whether 'cls' is a derived from another class or is the same class.
"""
#关于len(),注意len()和__len__()的关系,
class A:
def __init__(self,name,age,sex,cls):
self.name = name
self.age = age
self.sex = sex
self.cls = cls
def __len__(self):
return len(self.__dict__)
a1 = A('alex',81,'不详',2)
a1.hobby = '烫头'
a2 = A('egon',20,'不详',3)
a3 = A('yuan',21,'不详',4)
print(len(a1))
print(len(a2))
print(len(a3))
#关于hash(),注意hash()和__hash__()的关系,
class A:
def __init__(self,name,age,sex,cls):
self.name = name
self.age = age
self.sex = sex
self.cls = cls
def __hash__(self):
return 0
a1 = A('alex',81,'不详',2)
print(hash(a1))
#ps:
#自己定义的类,你需要实现其内部的__len__()等方法,
#否则你无法使用len()方法直接该类对象的长度,
#
#
#对一个对象,求hash值,
#这个值是相对固定的,
#如何理解?即在同一次运算中,同一对象的hash值是固定的,
#第二次运算可能就不相同了,
#
#内置的方法,比如len(),都和__len__()有很大的关系,
#其它还有很多方法,都是这个道理,比如__iter__(),
#反射,也可以叫自省,主要是指程序可以访问、检测和修改它本身状态或行为的一种能力,
#反省,好理解;反射,听着酷一些.其实说的是同一个.
# python面向对象中的反射:通过字符串!!!的形式操作对象相关的属性。
# 而python中的一切事物都是对象(也就是说都可以使用反射)
role = 123
print(eval('role')) #使用eval()很危险,如果传入了一个很危险的字符串,会怎么样???
class A:
role = 'Person'
def func(self):
print('*',self)
ret = input('>>>')
print(A.__dict__[ret])
print(getattr(A,'role')) # 从A的命名空间里找一个属性 ,直接就可以找到这个属性的值
f = getattr(A,'func');f(1) # 从A的命名空间里找一个方法 ,找到的是这个方法的内存地址
getattr(A,'func')(1)
A.func(1)
# 反射
# 正常情况下可以拿到类中的变量
# 那么如有有这个变量的字符串形式 就可以用反射获取这个值的所在空间,进而使用,
# 找一个属性 ,直接就可以找到这个属性的值
# 找一个方法 ,找到的是这个方法的内存地址
# hasattr() 判断一个命名空间中有没有这个名字
# getattr() 从命名空间中获取这个名字对应的值
# 类中的反射,可以获取其的属性和方法,
class A:
role = 'Person'
def func(self):
print('*'*self)
print(hasattr(A,'role'))
print(hasattr(A,'func'))
ret = input('>>>')
if hasattr(A,ret):
print(getattr(A,ret))
if hasattr(A,ret):
func = getattr(A,ret)
func(1)
# hasattr getattr
class A:
role = 'Person'
def __init__(self):
self.money = 500
def func(self):
print('*'*10)
a = A()
print(a.func)
getattr(a,'func')()
print(getattr(a,'money')) #OK,打印:500
print(getattr(a,'role')) #OK,打印:Person
print(getattr(A,'money')) #类的空间,访问对象的属性,报错:AttributeError: type object 'A' has no attribute 'money'
# 类使用类命名空间中的名字
# 对象使用对象能用的方法和属性
# 模块使用模块中的名字
import os ; getattr(os,'rename')('YQ_BAK','YQ')
import time # 一个py文件就是一个模块
time.time()
print(time.time())
print(getattr(time,'time')())
# 自己定义的模块,与系统自带一样的使用方法,#注意添加teacher模块文件,
# 'Teacher' -- Teacher #把字符串转换为类名,
import teacher #这里的红色报错,是pycharm提示的,python编译器会通过的,
alex = teacher.Teacher('alex')
print(alex.__dict__)
import teacher
t = 'Teacher'
Teach_class = getattr(teacher,t)
alex = Teach_class('alex')
print(teacher.Teacher('alex'))
a = 1
b = 2
def login():
print('执行login功能')
def register():
print('执行register功能')
import sys # 和python解释器相关的内容都在sys里
print(sys.modules['__main__']) #获取当前类所在的位置,
func = input('>>>')
if hasattr(sys.modules['__main__'],func):
getattr(sys.modules['__main__'],func)()
# 增删改 对象属性
class A:
def __init__(self,name):
self.name = name
def wahaha(self):
print('wahahahahaha')
a = A('alex')
print(a.__dict__)
setattr(a,'age',18) # 给a对象新增一个属性,类同a.age = 18
setattr(a,'name','egon') #有这个属性的话,就是修改;没有才是新添加,
delattr(a,'age') #类同del a.age
print(a.__dict__)
# 增删改 方法
class A:
def __init__(self,name):
self.name = name
def wahaha(self):
print('wahahahahaha')
def qqxing(self):
print('qqqqqxing',self.name)
a = A('alex')
setattr(A,'qqxing',qqxing)
setattr(a,'qqxing',qqxing) #通过对象,setattr方法,结果你把方法添加到了对象的空间中,这样是不好的,
print(A.__dict__)
print(a.__dict__)
A.qqxing(a)