Python反射

目录

1.复习:

2.今天的内容:反射

3.问题?


1.复习:

使用Python面向对象编写一个人类和学生类,其中人类是父类,有姓名,性别和年龄属性;学生类是子类,继承人类,特有的属性有学号和分数,特有的方法是学习和考试方法(在考试方法中使用随机数生成学生的分数)。

实例方法 形参:self,引用到对象本身。
类方法  @classmethod 形参:cls,引用到类本身,访问到类属性,不能引用实例属性。
静态方法 @staticmethod

系统不会自动加入类似于self或cls这样的形参:静态方法不能类属性和实例属性,”被隔离了”。

属性方法 @property 把方法的函数调用格式编程了属性方法,应用场景:属性的getter|setter访问器。

封装起来:__属性名

代码如下:

class Student(Person):
    def __init__(self,name,gender,no,age = 0,score = 0.0):
        # 子类的构造方法需要像父类的构造方法传递参数,必须手工调用父类的构造方法
        Person.__init__(self,name,gender,age)
        # super(Student,self).__init__(name,gender,age)
        self.No = no
        self.Score = score
    @property
    def No(self):
        return self.__no
    @No.setter
    def No(self,no):
        if 1<=no<100:
            self.__no = no
        else:
            print("学生的学号有效范围[1,100)")

    @property
    def Score(self):
        return self.__score

    @Score.setter
    def Score(self, score):
        if 0 <= score <= 100:
            self.__score = score
        else:
            print("学生的分数有效范围[0,100]")

    def study(self):
        print("%s正在学习..."%(self.Name))
    def exam(self):
        print("%s已经参加了考试"%(self.Name))
        self.Score = random.randint(0,100)
        print("其分数为%f"%(self.Score))


s = Student("ZhangSan","男",1,16)
s.study()
s.exam()

2.今天的内容:反射

正向开发过程:

分析师进行系统分析设计,得到类图(类,属性,方法,类和类之间的关系)

开发工程师进行编码工作,实现类图中的类,创建对象,访问对象的属性,

调用对象的方法。

反射:开发工程师得到别的开发工程师传递过来的对象,对象所属的类

3.问题?

不太清楚对象有那些属性,那些方法?猜测的时候,得到的只是一些字符串,代码中需要访问的是对象的属性和方法,怎样将字符串映射成对象、对象的属性、对象的方法?

Python中的反射完成此工作。

可以对上述对象进行(增删改查):

hasattr
setattr 新增
getattr 获取
delattr

删除

  代码如下:

"""
父类:人类Person
     封装了类的属性,只有本类的方法可以直接访问属性,
     提供访问属性的getter|setter访问器(属性方法)
     属性的有效数据一般需要经过数据检验的
     规定:只在属性的setter访问器进行属性的写操作
     数据检验的代码只写在setter访问器中
"""
import random


class Person(object):
    def __init__(self,name,gender,age = 0):
        # 通过setter访问器给属性赋初始值
        self.Name = name
        self.Gender = gender
        self.Age = age

    @property
    def Name(self):
        return self.__name
    @Name.setter
    def Name(self,name):
        if len(name) == 0:
            print("人的姓名不能为空字符串")
        else:
            self.__name = name
    @property
    def Gender(self):
        return self.__gender
    @Gender.setter
    def Gender(self,gender):
        if gender == "男" or gender == "女":
            self.__gender = gender
        else:
            print("人的性别只能是男或者女")
    @property
    def Age(self):
        return self.__age
    @Age.setter
    def Age(self,age):
        if 0<=age<200:
            self.__age = age
        else:
            print("人的年龄的有效范围只能是[0,200)")

class Student(Person):
    def __init__(self,name,gender,no,age = 0,score = 0.0):
        # 子类的构造方法需要像父类的构造方法传递参数,必须手工调用父类的构造方法
        Person.__init__(self,name,gender,age)
        # super(Student,self).__init__(name,gender,age)
        self.No = no
        self.Score = score
    @property
    def No(self):
        return self.__no
    @No.setter
    def No(self,no):
        if 1<=no<100:
            self.__no = no
        else:
            print("学生的学号有效范围[1,100)")

    @property
    def Score(self):
        return self.__score

    @Score.setter
    def Score(self, score):
        if 0 <= score <= 100:
            self.__score = score
        else:
            print("学生的分数有效范围[0,100]")

    def study(self):
        print("%s正在学习..."%(self.Name))
    def exam(self):
        print("%s已经参加了考试"%(self.Name))
        self.Score = random.randint(0,100)
        print("其分数为%f"%(self.Score))


s = Student("ZhangSan","男",1,16)
# 你得到了s对象
# 假设你向打印s对象的属性值 ,
# 猜想:salary
#print(s.salary)  # 抛出异常对象了,代码中如果没有处理异常,后续的代码就不会被执行了
# 使用反射来访问s对象的salary属性
# 好处:控制访问的场景
if hasattr(s,"salary"):
    print(getattr(s,"salary"))
else:
    print("s对象没有名称为salary的属性")

if hasattr(s,"exam"):
    m = getattr(s,"exam")
    m()
else:
    print("s对象没有exam属性")

# 如果s对象没有play方法,就动态的添加play方法
if not hasattr(s,"play"):
    setattr(s,"play",lambda self,hours:print(self.Name,"玩了",hours,"个小时"))
#动态调用方法
m = getattr(s,"play")
m(s,2)

#删除属性
print("Age = ",s.Age)
delattr(s,"__age")
print("Age = ",s.Age)

x = 10
print(x)

原文:Python反射

接下:

你可能感兴趣的:(PYTHON,python)