@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__],'全局变量名')
# 从当前文件中寻找全局变量对应的值/地址