20180730 (面向对象的反射,内置方法)
一.面向对象的前期总结
1.类
类的定义:
静态属性(变量/字段) 类属性(变量/字段) 直接写在类中,全大写
动态属性(方法) 方法(函数) self
类方法 @classmethod cls
静态方法 @staticmethod 没有默认参数
属性 @property
类的调用:
对象名.动态属性() / 类名.动态属性(对象名)
类名.静态属性 / 对象名.静态属性
类名.类方法() / 对象名.类方法()
类名.静态方法 / 对象.静态方法()
2.对象
对象的命名空间中有什么?
属性
对象能调用的:
对象属性
类中的普通方法
3.私有
狭义的封装里面的私有:
静态属性(变量/字段) 动态属性(方法) 类方法 静态方法 属性
私有的特点:
只能在类的内部调用
不能被继承
什么时候可以用私有:
当不想被外部调用也不想被继承,只想在类内部使用的时候
当在外部使用的时候,想给用户的使用前后直接加上某些功能的时候(私有+property使用)
class A:
def __init__(self,name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self,new_name):
if type(new_name) is str:
self.__name = new_name
a = A("alex")
a.name = "123"
print(a.name)
print(a.__dict__)
二.反射
定义:用字符串数据类型的变量名来访问这个变量的值
getattr hasattr setattr delattr
1.类: (getattr(类名/对象名,"静态属性名/动态方法"))
静态变量(属性)
class Student:
ROLE = "student"
print(getattr(Student,"ROLE")) (第一个参数为类名,第二个参数为类空间里的静态变量的名)
类方法:
class Student:
ROLE = "student"
@classmethod
def func(cls):
print("查看类方法")
getattr(Student,"func")()
静态方法:
class Student:
ROLE = "student"
@staticmethod
def func():
print("查看静态方法")
num = input(">>>")
if hasattr(Student,num): hasattr是查看第二个参数是不是在第一个参数的类空间里
getattr(Student,num)()
2.对象
对象属性 普通方法
class A:
def __init__(self,name):
self.name = name
def func(self):
print("in func")
a = A("alex")
getattr(a,"func")()
3.模块
import os (别人写好的python代码的结合)
getattr(os,"rename")(原文件名,新文件名)
getattr(os,"rename") == os.rename 都是内存地址
4.反射自己模块中的内容
import 相当于导入一个模块
模块哪个导入了,哪个没有导入,都应该在python的解释器里应该记录下来
import sys 是一个模块
这个模块里的所有方法都是和python解释器相关的
sys.module
这个方法表示所有在当前这个python程序中导入的模块
import sys
def wahaha():
print("娃哈哈")
def qqxing():
print("QQ星")
file = sys.modules["__main__"] (内存地址)<module '__main__' from 'E:/python作业/Python面向对象/20180730/练习.py'>
getattr(file,"wahaha")()
getattr(file,"qqxing")()
5.setattr(对象名,"对象属性名/普通方法","修改对象属性的值") (修改对象属性的值)
class Student:
def __init__(self,name,age,sex):
self.name = name
self.age = age
self.sex = sex
a = Student("alex",34,"男")
setattr(a,"name","taibai")
print(a.name)
print(a.__dict__)
6.delattr(对象名,"对象属性名/普通方法") (删除对象属性)
class A:
def __init__(self,name,age):
self.name = name
self.age = age
a = A("alex",22)
delattr(a,"name")
print(a.__dict__)
三.内置方法
__名字__
类中的特殊方法/内置方法 双下方法 魔术方法 magic method (类中的每一个双下方法都有它自己的特殊意义)
1.__call__ (相当于对象) 在类写装饰器的时候必须用
class A:
def __call__(self, *args, **kwargs):
print("执行call方法")
a = A()
a() 对象() 相当于调用__call__方法
A()() 类名()() 相当于实例化得到一个对象,再对 对象() ===>也相当于调用__call__方法
class A:
def __call__(self, *args, **kwargs):
print("执行了call方法")
class B:
def __init__(self,cls):
print("在实例化A前做了一些事情")
self.a = cls() =====>self.a是A的实例化对象
self.a()
print("在实例化A之后做了一些事情")
B(A)
2.__len__ len(obj)相当于调用了这个obj的__len__方法
class A:
def __init__(self):
self.lst = [1,2,3,4,5]
def __len__(self):
print("执行__len__")
return len(self.lst) --len__方法中 return的值就是len函数的返回值,这个返回值必须是int类型,如果一个obj(对象)没有__len__方法,那么len函数就会报错
l = A()
print(len(l)) ====>5
3.__new__ (构造方法) 开辟内存空间的构造方法 (重点)
__init__ 初始化方法
class A:
def __new__(cls, *args, **kwargs): A里面没有new方法,只能调用object类里面的new方法
a = object.__new__(cls)
print("在new方法里",a)
return a
def __init__(self):
print("在init方法里")
a = A()
new 方法在实例化的过程中最先执行的方法,__init__之前执行new来创建一个对象空间
例题:写一个单例类
class A:
__B = None
def __new__(cls, *args, **kwargs):
if not cls.__B: =====>
cls.__B = object.__new__(cls)
return cls.__B
def __init__(self,name):
self.name = name
s1 = A("alex")
s2 = A("wusir")
print(s1.__dict__)
print(s2.__dict__)
4.__str__ str(obj(对象)) %s print
class A:
def __str__(self):
return self.name
def __init__(self,name):
self.name = name
a = A("alex")
print(a)
print(一个对象) 相当于调用一个对象的__str__方法
str(一个对象) 相当于执行obj.__str__方法 print(str(对象名))
"%s" % 一个对象 相当于执行obj.__str__方法 print("学生:%s" % 对象名)
class Student:
def __str__(self):
return "学生是:%s %s %s" % (self.school,self.cla,self.name)
def __init__(self,name,school,cla):
self.name = name
self.school = school
self.cla = cla
s1 = Student("刘某某","old boy","py14")
print(s1)
s2 = Student("张某某","old boy","py14")
print(s2)
5.__repr__ repr(obj对象) %r repr是str的备胎
repr(obj) %r 都相当于调用了__repr__
例如:
a = "123"
print(repr(a))
在子类中使用__str__,先找子类中的__str__.如果子类中没有的话,就找除了object类的父类中的__str__的方法,如果父类中也没有,就找子类中的__repr__的方法,如果子类中没有,找父类中的__repr__,如果都没有,就找object类中的__str__方法
例如:
class A:
def __init__(self,name):
self.name = name
def __str__(self):
return "**%s**" % self.name
def __repr__(self):
return "*%s" % self.name
class B(A):pass
# def __str__(self):
# return "**%s" % self.name
# def __repr__(self):
# return self.name
a = B("alex")
print(a)
print(str(a),repr(a))
所有的双下方法,没有需要你在外部直接调用的,而是总有一些其它的内置函数,特殊的语法,来自动触发这些双下方法