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

所有的双下方法,没有需要你在外部直接调用的,而是总有一些其它的内置函数,特殊的语法,来自动触发这些双下方法

原文地址:https://www.cnblogs.com/lhy979/p/9393123.html