day30 Pyhton 面向对象 反射

@property
# 例1 - 1 (某一个属性如果是通过计算得来的,那么计算的过程写在方法里,把这个方法伪装成属性)
from math import pi
# class Circle:
#     def __init__(self,r):
#         self.r = r
#
#     @property  # 把一个方法伪装成属性 源码中有人写
#     def area(self):   # 被property装饰器装饰的方法不能传递除self以外的参数
#         return pi*self.r**2
#
#     @property
#     def perimeter(self):
#         return self.r*pi*2
#
# c1 = Circle(5)
# print(c1.area)
# c1.r = 10
# print(c1.area)
# 圆c1的面积周长
# alex的名字

class Circle:
    def __init__(self,r):
        self.r = r
        self.area = pi*self.r**2
        self.perimeter = self.r*pi*2

c1 = Circle(5)
print(c1.area)#78.53981633974483
c1.r = 10
print(c1.area)#78.53981633974483  area的值在第一次赋值后就固定了

# 例2-1 某一个属性需要被私有化,又需要能被外部查看,这种情况,把这个属性通过方法返回,方法伪装成属性
# class Person:
#     def __init__(self,name):
#         self.__name = name  # 不让外面随便修改
#     def get_name(self):
#         return self.__name
#
# alex = Person('alex')
# print(alex.get_name())

# 例2-2
# class Person:
#     def __init__(self,name):
#         self.__name = name  # 不让外面随便修改
#
#     @property
#     def name(self):
#         return self.__name
#
# alex = Person('alex')
# print(alex.name)

# 例2-3 修改属性值
class Person:
    def __init__(self,name):
        self.__name = name  # 不让外面随便修改

    @property
    def name(self):
        return self.__name

    @name.setter   # 之前必须有一个同名的方法被property装饰过
    def name(self,new_name):
        if type(new_name) is str:
            self.__name = new_name

    @name.deleter
    def name(self):
        del self.__name

    # def set_name(self,new_name):
    #     if type(new_name) is str:
    #         self.__name = new_name

alex = Person('alex')
print(alex.name)
# alex.set_name(123)
# print(alex.name)
alex.name = 'alex_sb'
print(alex.name)
del alex.name   # 删除name属性
print(alex.name)#'Person' object has no attribute '_Person__name'

# 你有没有什么时候
# 能拿到 字符串
# 你就希望能够通过这个字符串 --> 程序中的变量名(类名函数名变量名方法名对象名)

# class Manager:pass
# class Student:pass
# class Teacher:pass
# identify = 'Student'
# print(eval(identify)())
# if 'identify' == 'Manager':
#     Manager()
# elif 'identify' == 'Student':
#     Student()
# elif 'identify' == 'Teacher':
#     Teacher()

# class Person:
#     role = '人类'
#     Country = '中国'
#
# attr = input('>>>')  # role 人类
# #                    # Country 中国
# # print(getattr(Person,'role'))
# # print(getattr(Person,'Country'))
# if hasattr(Person,attr):
#     print(getattr(Person,attr))

# if attr == 'role':
#     print(Person.role)
# elif attr == 'Country':
#     print(Person.Country)


# getattr(命名空间,'key')  == 命名空间.key
# 所有的a.b都可以被反射成getattr(a,'b')

# 反射类中的方法
# class Person:
#     role = '人类'
#     @staticmethod
#     def show_courses():
#         print('所有课程')
# Person.role  == getattr(Person,'role')
# Person.show_courses() == getattr(Person,'show_courses')()
# ret = getattr(Person,'show_courses')
# ret()

# 有一个类,有很多静态属性,也有很多静态方法/类方法
# 用户输入input任意的属性名或者方法名,
# 如果是属性 直接打印  - 用到一个内置函数
# 如果是方法 直接调用  - 用到一个内置函数
# 要求程序不报错
# 什么是封装?
    # 广义上
    # 狭义上
# 类的命名空间(类的对象共享的资源) :
    # 静态属性
    # 类方法
    # 静态方法
    # 普通方法
    # property方法
# 对象的命名空间(对象独有的资源):
    # 对象的属性
    # 对象的方法

# 狭义上
    # 私有成员
    # 在类的内部 __成员名
    # 在类的外部 不能用
    # 在存储的空间中 _类名__成员名

# 1.私有成员不能在类的外部使用,也不能被继承
# 无论在哪个类中调用私有成员,一定是在哪个类调,就用哪个类的
# 2.类中的三个装饰器方法
# 先实现功能
# 某个方法如果用到self 传self
# 某个方法如果没用到self,用到类 传cls ,加@classmethod装饰器      *****
# 某个方法如果没用到self,没用到类  啥也不传,加@staticmethod装饰器
# 但凡是不需要传self参数的,都不需要实例化,直接使用类调用就可以了
# @property : 伪装一个方法成为一个属性,调用的时候不需要加()

# 3.反射 非常重要
# a.b这样的情况
# 如果由于某种原因,b变成了 'b'
# 那么就是用getattr(a,'b')的形式获取b对应的值
# 如果b是一个值 那么getattr的结果就是值
# 如果b是一个地址 那么getattr的结果就是地址,地址()就是执行
# from sys import modules
# getattr(modules[__name__],'全局变量名')
# 从当前文件中寻找全局变量对应的值/地址










原文地址:https://www.cnblogs.com/pythonz/p/10023338.html