一、property
装饰器是在不修改被装饰对象的源代码以及调用方式的前提下,为被装饰对象添加新功能的可调用对象。
property是一个装饰器,是用来绑定给对象的方法伪造成一个数据属性
#案例1
class People:
def __init__(self, name, height, weight):
self.name = name
self.height = height
self.weight = weight
# 定义函数的原因1:
# 1、从bmi公式上看,应该是触发功能计算得到的
# 2、bmi是随着身高、体重的变化而动态变化的,不是一个固定的值
# 但是bmi听起来更像一个数据属性,而非功能
@property
def bmi(self):
return self.weight / (self.height ** 2)
obj1 = People('egon', 1.80, 70)
print(obj1.bmi) # 直接调,不用加括号
人的正常思维逻辑
使用者.name去用
案例2
方式1:
class People:
def __init__(self, name):
self.__name = name
def get_name(self):
return self.__name
def set_name(self, val):
if type(val) is not str:
print('必须传入字符串')
return
self.__name = val
def del_name(self):
print('不让删除')
name = property(get_name, set_name, del_name)
obj1 = People('egon')
print(obj1.name) # 查找操作
obj1.name = '18' # 更改操作
print(obj1.name)
del obj1.name # 删除操作
-----------------输出结果---------------------
egon
不让删除
方式二:
第一步:先将函数名字都改成name
第二步:在函数的上方添加@
class People:
def __init__(self, name):
self.__name = name
@property
def name(self):
return self.__name
@name.setter
def name(self, val):
if type(val) is not str:
print('必须传入字符串')
return
self.__name = val
@name.deleter
def name(self):
print('不让删除')
obj1 = People('egon')
print(obj1.name) # 查看名字
obj1.name = 'EGON' # 更改名字
print(obj1.name)
del obj1.name # 删除名字
-----------输出结果----------
egon
EGON
不让删除
二、绑定方法
特殊之处在于将调用者本身当作第一个参数自动传入
1、绑定给对象的方法:调用者是对象,自动传入的是对象
2、绑定给类的方法:调用者类,自动传入的是类
classmethod绑定方法
import settings
class Mysql:
def __init__(self, ip, port):
self.ip = ip
self.port = port
def func(self):
print("%s:%s" % self.ip, self.port)
@classmethod # 将下面的函数装饰成绑定给类的方法
def from_conf(cls):
print(cls)
return cls(settings.IP, settings.PORT)
# 应用场景很窄,给你提供一种新的造对象的方式
# 来自于配置文件和其他地方
obj1 = Mysql('1.1.1.1', 3306)
obj2 = Mysql.from_conf()
print(obj2.__dict__)
staticmethod非绑定方法
静态方法:没有绑定给任何人:调用者可以是类、对象、没有自动传参的效果
class Mysql:
def __init__(self, ip, port):
self.ip = ip
self.port = port
@staticmethod # 将下述函数装饰成一个静态方法
def create_id(): # 如果有参数,必须传参,需要手动传
import uuid
return uuid.uuid4()
obj1 = Mysql('1.1.1.1', 3306)
print(Mysql.create_id())
print(obj1.create_id())
三、继承
继承是创建新类的一种方式
新建的类称之为子类
被继承的类称之为父类、基类、超类
继承的特点是:子类可以遗传父类的属性
类是用解决对象之间冗余问题的
而继承则是来解决类与类之间冗余问题的
在python中支持多继承
class Parent1(object): # 考虑代码兼容问题,可以在()加object
pass # 在python3中所有的类都是新式类
class Parent2(object):
pass
class Sub1(Parent1):
pass
class Sub2(Parent1, Parent2):
pass
print(Sub1.__bases__)
print(Sub2.__bases__)
但凡是继承了object类的子类以及该子类的子子孙孙类都是新式类
反之就是经典类
在python2中有新式类与经典类之分,在python3中全都是新式类
print(Parent1.__bases__)
print(Parent2.__bases__)
多继承的优缺点
优点:子类可以同时遗传多个父类的属性,最大限度地重用代码
缺点:
1、违背人的思维习惯:继承表达的是一种什么'是'什么的关系
2、代码的可读性变差
继承背景下的属性查找
# 示例1
class Bar:
def f1(self):
print('Bar.f1')
def f2(self):
print('Bar.f2')
self.f1() # obj.f1()
class Foo(Bar):
def f1(self):
print("Foo.f1")
obj = Foo()
obj.f2()
--------输出结果---------
Bar.f2
Foo.f1
# 示例2
class Bar:
def __f1(self): # _Bar__f1
print('Bar.f1')
def f2(self):
print('Bar.f2')
self.__f1() # self._Bar_f1
class Foo(Bar):
def __f1(self): # _Foo__f1
print("Foo.f1")
obj = Foo()
obj.f2()
----------输出结果---------
Bar.f2
Bar.f1
。