python学习之老男孩python全栈第九期_day026知识点总结——封装、property、类方法、初识反射

一. 封装

class Room:
    def __init__(self, name, length, width):
        self.__name = name
        self.__length = length
        self.__width = width
    def get_name(self):
        return self.__name
    def set_name(self, newName):
        if type(newName) is str and newName.isdigit() == False:
            self.__name = newName
        else:
            print('不合法的姓名')
    def area(self):
        return self.__length * self.__width

jin = Room('金老板的小窝', 5, 10)
print(jin.area())
jin.set_name('2')
print(jin.get_name())
# 假设父类的私有属性,能被 子类 调用吗? 不能
class Foo:
    __key = '123'       # _Foo__key

class Son(Foo):
    print(Foo.__key)    # _Son__key
会用到私有的这个概念的场景
1. 隐藏起一个属性 不想让类的外部调用
2. 我想保护这个属性,不想让属性随意被改变
3. 我想保护这个属性,不被子类继承

 

二. property

 内置装饰器函数,只在面向对象中使用

from math import pi
class Circle:
    def __init__(self, r):
        self.r = r
    @property
    def perimeter(self):
        return 2 * pi * self.r
    @property
    def area(self):
        return pi * self.r**2
c1 = Circle(10)
print(c1.area)              # 圆的面积
print(c1.perimeter)         # 圆的周长

class Count_bmi:
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height
    @property
    def bmi(self):
        return self.weight / (self.height**2)
kidd = Count_bmi('KID', 51, 1.68)
print(kidd.bmi)
kidd.bmi = 23         # 不能改

class Person:
    def __init__(self, name):
        self.__name = name
    @property
    def name(self):
        return self.__name + 'SB'
    @name.setter
    def name(self, newName):
        self.__name = newName
p = Person('qqq')
print(p.name)
p.name = 'ppp'
print(p.name)

class Goods:            # 定义一个超市物品
    discount = 0.5      # 全场5折
    def __init__(self, name, price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return self.__price * Goods.discount

apple = Goods('苹果',4)
print(apple.price)
# 属性:查看 修改 删除
# 刚才学了 查看 修改 ,接下来看看怎么删除(不常用)
class Person:
    def __init__(self, name):
        self.__name = name
    @property
    def name(self):
        return self.__name
    @name.deleter
    def name(self):
        print('执行了这个方法')
        del self.__name
    @name.setter
    def name(self,newName):
        self.__name = newName
p = Person('二哥')
print(p.name)
del p.name
print(p.name)       # 在查看就会报错,因为已经删除

 

三. 类方法

class Goods:            # 定义一个超市物品
    __discount = 0.5      # 全场5折
    def __init__(self, name, price):
        self.name = name
        self.__price = price
    @property
    def price(self):
        return self.__price * Goods.__discount
    @classmethod        # 把一个方法变声一个类中的方法,这个方法就直接可以被类调用,不需要依托任何对象
    def change_discount(cls, newDiscount):      # 修改折扣
        cls.__discount = newDiscount
apple = Goods('苹果',4)
print(apple.price)
Goods.change_discount(0.8)          # Goods.change_discount(Goods)
print(apple.price)
当这个方法的操作只涉及静态属性时,就应该使用calssmethod来装饰这个方法
class Login:
    def __init__(self, name, password):
        self.name = name
        self.password = password
    def login(self):
        pass
    @staticmethod
    def get_usr_pwd():              # 静态方法
        usr = input('用户名:')
        pwd = input('密码:')
        Login(usr,pwd)
Login.get_usr_pwd()
在完全面向对象的程序中
如果一个函数既和对象没有关系 也和类没有关系 那么就用staticmethod 将这个函数改变成一个静态方法

类方法 和 静态方法 都是类调用的
那么对象可以调用 类方法 和 静态方法 吗?    可以    一般情况下  推荐用类名调用
类方法 有一个默认参数 cls 代表这个类,可以改变这个名字,但不建议改变(与self代表对象似的)
静态方法 没有默认的参数 就像函数一样

 

四. 初识反射

name = 'alex'

class Teacher:
    dic = {
        '查看学生信息':'show_student',
        '查看讲师信息':'show_teacher'
    }
    def show_student(self):
        print('show_student')
    def show_teacher(self):
        print('show_teacher')
    @classmethod
    def func(self):
        print('哈哈哈')
alex = Teacher()
for k in Teacher.dic:
    print(k)
key = input('输入需求:')
# print(Teacher.dic[key])
if hasattr(alex,Teacher.dic[key]):
    func = getattr(alex,Teacher.dic[key])
    func()

# # alex.show_student()   'show_student'
# func = getattr(alex,'show_student')
# func()



# hasattr   getattr     delattr
# if hasattr(Teacher,'dic'):
#     ret = getattr(Teacher,'dic')        # Teacher.dic       # 类也是对象
#     ret2 = getattr(Teacher,'func')         # 类.方法  Teacher.func
#     print(ret)
#     print(ret2)
#     ret2()
# menu = Teacher.dic
# # for k in menu:
# #     print(k)
# 通过反射
# 对象名 获取对象属性 和普通方法
# 类名 获取静态属性 和 类方法 和 静态方法
普通方法 带self
静态方法 @staticmethod
类方法 @classmethod
属性方法 @property
原文地址:https://www.cnblogs.com/lpgit/p/9409357.html