day26_python

参考Eva_J的博客,原文连接:https://www.cnblogs.com/Eva-J/p/7277026.html

前戏

'''
python 没有接口类,由抽象类,abc模块中的metaclass = ABCMeta,@abstructmethod
本质上是做代码规范用的,希望在子类中实现和父类方法名字完全一样的方法
在java的角度上,是有区别的,java没有多继承,所以为了接口隔离原则,设计了接口的概念,支持多继承
java本来就支持单继承,就有了抽象类
python支持多继承和单继承,模糊了接口类,没有内置接口类
多态
python天生支持多态
鸭子类型,不依赖父类的情况下实现两个相似的类中的同名方法
私有化之后就不能从类的外部直接调用了
静态属性 方法 对象属性都可以私有化
这种私有化只是从代码级别做了变形,并没有真的约束
变形机制__类名__名字在类外调用,内部直接__名字调用
'''

from math import pi

例子

class Room:
    def __init__(self, name, length, width) -> None:
        self.__name = name
        self.__length = length
        self.__width = width

    def get_name(self):
        return self.__name

    def set_name(self, new):
        if type(new) is str and new.isdight() is False:
            self.__name = new
        else:
            print('不合法')

    def area(self):
        return self.__length*self.__width

父类的私有属性不能被子类调用

class Foo:
    __key = '123'


class Son(Foo):
    print(Foo.__key)

会用到私有概念的场景

隐藏起来一个属性,不想让类的外部调用
保护属性,不让属性随意被改变,不被子类继承

property, clasamethod, staticmethod

property

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

例子1

property让函数伪装成属性

class Circle:
    def __init__(self, r) -> None:
        self.r = r

    @property
    def perimeter(self):
        return 2*pi*self.r

    @property  # 函数不能传参数
    def area(self):
        return self.r**2*pi


c1 = Circle(5)
print(c1.area)
print(c1.perimeter)  # 加property 不用加括号,伪装成属性

例子2

setter实现对对象的修改

class Person:
    def __init__(self, name, high, weight) -> None:
        self.name = name
        self.__high = high
        self.__weight = weight

    @property
    def bmi(self):
        return self.__weight/self.__high**2

    @bmi.setter   # 先有property方法才能用setter实现对对象的修改
    def bmi(self):
        return self.__weight/self.__high**2


jin = Person('金老板', 1.6, 90)
print(jin.bmi)
jin.name = '泰哥'

classmethod

把一个方法变成一个类中的方法,这个方法可以直接被类调用,不需要依托任何对象

class Goods:
    __discount = 0.5

    def __init__(self, name, price) -> None:
        self.name = name
        self.__price = price

    @property
    def price(self):
        return self.__price*Goods.discount

    @classmethod 
    def change_dis(cls, new_dis):  # 修改折扣
        cls.__discount = new_dis


apple = Goods('苹果', 5)
print(apple.prices)

属性 的 删除

class Person:
    def __init__(self, name) -> None:
        self.__name = name

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

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

    @name.setter
    def name(self, newName):  # 使用setter只能传一个参数
        self.__name = newName


brother = Person('二哥')
print(brother.name)
del brother.name
print(brother.name)

staticmethod和classmethod

类里面的操作行为
当这个方法的操作只涉及静态属性的时候,就应该使用classmethod来装饰这个方法

class Login:
    def __init__(self, name, password) -> None:
        self.name = name
        self.pwd = password

    def login():
        pass

    @staticmethod   # 静态方法 与类中的self无关
    def get_user_pwd():
        usr = input()
        pwd = input()
        Login(usr, pwd)


Login.get_user_pwd()
# 在完全面向对象的程序中,如果一个函数既和对象没有关系,也和类没有关系
# 那么就用staticmethod将这个函数变成一个静态方法
# 类方法何静态方法都是类调用的,对象也可以调用类方法何静态方法,推荐使用类名调用
# 默认参数cls 代表类
# 静态方法没有默认的参数,就像函数一样

反射

class Teacher:
    dic = {'查看学生信息': 'show_student', '查看讲师信息': 'show_teacher'}

    def show_student(self):
        print('show_student')

    def show_teacher(slef):
        print('show_teacher')

    @classmethod
    def func(cls):
        print('hahhaha')


for k in Teacher.dic:
    print(k)
key = input('need')
print(Teacher.dic[key])

alex = Teacher()
if hasattr(alex, Teacher.dic[key]):
    func = getattr(alex, Teacher.dic[key])
    func()
else:
    print('No')
# hasattr getattr delattr
if hasattr(Teacher, 'dic4'):  # hasattr返回布尔类型
    ret = getattr(Teacher, 'dic4')
ret2 = getattr(Teacher, 'func')
print(ret)
ret2()
'''
对象名获取对象属性何普通方法
类名获取静态属性何类方法和静态方法
普通方法self
静态方法@staticmethod
类方法@classmethod
属性方法@property
'''
posted @ 2021-08-28 01:10  二儿八月  阅读(31)  评论(0)    收藏  举报