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
'''

浙公网安备 33010602011771号