day-6 and day-7:面向对象
1.1类、对象、实例、实例化
类:具有相同特征的一类事物
对象/实例:具体的某一个事物
实例化:类——>对象的过程
def functionName(args): '函数文档字符串' 函数体 ''' class 类名: '类的文档字符串' 类体 ''' #我们创建一个类 class Data: pass
1.2.实例化:类名加括号就是实例化,会自动触发__init__函数的运行,可以用它来为每个实例定制自己的特征
实例化的过程就是类——>对象的过程
创建一个对象/实例就会创建一个对象/实例的名称空间,存放对象/实例的名字,称为对象/实例的属性
在obj.name会先从obj自己的名称空间里找name,找不到则去类中找,类也找不到就找父类...最后都找不到就抛出异常
2.1继承
继承是一种创建新类的方式,在python中,新建的类可以继承一个或多个父类,父类又可称为基类或超类,新建的类称为派生类或子类
python中类的继承分为:单继承和多继承
2.1
1、Python的类可以继承多个类
2、Python的类如果继承了多个类,那么其寻找方法的方式有两种,分别是:深度优先和广度优先
- 当类是经典类时,多继承情况下,会按照深度优先方式查找
- 当类是新式类时,多继承情况下,会按照广度优先方式查找
-
经典类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去D类中找,如果D类中么有,则继续去C类中找,如果还是未找到,则报错
新式类:首先去A类中查找,如果A类中没有,则继续去B类中找,如果B类中么有,则继续去C类中找,如果C类中么有,则继续去D类中找,如果还是未找到,则报错
注意:在上述查找过程中,一旦找到,则寻找过程立即中断,便不会再继续找
3、抽象类与接口类
声明某个子类兼容于某基类,定义一个接口类Interface,接口类中定义了一些接口名(就是函数名)且并未实现接口的功能,子类继承接口类,并且实现接口中的功能
3.1接口类
# 创建一个规范
from abc import ABCMeta,abstractmethod
class Payment(metaclass=ABCMeta): # 抽象类 接口类 规范和约束 metaclass指定的是一个元类
@abstractmethod
def pay(self):pass # 抽象方法
class Alipay(Payment):
def pay(self,money):
print('使用支付宝支付了%s元'%money)
class QQpay(Payment):
def pay(self,money):
print('使用qq支付了%s元'%money)
class Wechatpay(Payment):
# def pay(self,money):
# print('使用微信支付了%s元'%money)
def recharge(self):pass
def pay(a,money):
a.pay(money)
a = Alipay()
a.pay(100)
pay(a,100) # 归一化设计:不管是哪一个类的对象,都调用同一个函数去完成相似的功能
q = QQpay()
q.pay(100)
pay(q,100)
w = Wechatpay()
pay(w,100) # 到用的时候才会报错
# 抽象类和接口类做的事情 :建立规范
# 制定一个类的metaclass是ABCMeta,
# 那么这个类就变成了一个抽象类(接口类)
# 这个类的主要功能就是建立一个规范
3.2 抽象类
抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化
4 封装
调用被封装的内容时,有两种情况:
- 通过对象直接调用
- 通过self间接调用
5 面向对象的公有与私有
- 公有成员,在任何地方都能访问
- 私有成员,只有在类的内部才能方法
5.1 静态字段(静态变量)
- 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
- 私有静态字段:仅类内部可以访问;
5.2 普通字段(对象属性)
- 公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问
- 私有普通字段:仅类内部可以访问
5.3 方法:
- 公有方法:对象可以访问;类内部可以访问;派生类中可以访问
- 私有方法:仅类内部可以访问;
6 面向对象成员
6.1 字段
字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,
- 普通字段属于对象
- 静态字段属于类
- 静态字段在内存中只保存一份
- 普通字段在每个对象中都要保存一份
- 应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段
6.2 方法
方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。
- 普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self;
- 类方法:由类调用; 至少一个cls参数;执行类方法时,自动将调用该方法的类复制给cls;
- 静态方法:由类调用;无默认参数;
class Foo:
def __init__(self, name):
self.name = name
def ord_func(self):
""" 定义普通方法,至少有一个self参数 """
# print self.name
print '普通方法'
@classmethod
def class_func(cls):
""" 定义类方法,至少有一个cls参数 """
print '类方法'
@staticmethod
def static_func():
""" 定义静态方法 ,无默认参数"""
print '静态方法'
# 调用普通方法
f = Foo()
f.ord_func()
# 调用类方法
Foo.class_func()
# 调用静态方法
Foo.static_func()
相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。
不同点:方法调用者不同、调用方法时自动传入的参数不同。
6.3 属性
property是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值
class Goods(object):
def __init__(self):
# 原价
self.original_price = 100
# 折扣
self.discount = 0.8
@property
def price(self):
# 实际价格 = 原价 * 折扣
new_price = self.original_price * self.discount
return new_price
@price.setter
def price(self, value):
self.original_price = value
@price.deltter
def price(self, value):
del self.original_price
obj = Goods()
obj.price # 获取商品价格
obj.price = 200 # 修改商品原价
del obj.price # 删除商品原价
7. 面相对象的特殊成员及相关内置函数
7.1 isinstance与issubclass
isinstance(obj,cls)检查是否obj是否是类 cls 的对象
issubclass(sub, super)检查sub类是否是 super 类的派生类
7.2 反射
python面向对象中的反射:通过字符串的形式操作对象相关的属性。python中的一切事物都是对象(都可以使用反射)
对实例化对象的实例:
下列方法适用于类和对象(一切皆对象,类本身也是一个对象)
class Foo: f = '类的静态变量' def __init__(self,name,age): self.name=name self.age=age def say_hi(self): print('hi,%s'%self.name) obj=Foo('egon',73) #检测是否含有某属性 print(hasattr(obj,'name')) print(hasattr(obj,'say_hi')) #获取属性 n=getattr(obj,'name') print(n) func=getattr(obj,'say_hi') func() print(getattr(obj,'aaaaaaaa','不存在啊')) #报错 #设置属性 setattr(obj,'sb',True) setattr(obj,'show_name',lambda self:self.name+'sb') print(obj.__dict__) print(obj.show_name(obj)) #删除属性 delattr(obj,'age') delattr(obj,'show_name') delattr(obj,'show_name111')#不存在,则报错 print(obj.__dict__)
对类的示例:
class Foo(object):
staticField = "old boy"
def __init__(self):
self.name = 'wupeiqi'
def func(self):
return 'func'
@staticmethod
def bar():
return 'bar'
print getattr(Foo, 'staticField')
print getattr(Foo, 'func')
print getattr(Foo, 'bar')
对当前模块的示例
import sys
def s1():
print 's1'
def s2():
print 's2'
this_module = sys.modules[__name__]
hasattr(this_module, 's1')
getattr(this_module, 's2')
其他模块的示例
#一个模块中的代码
def test():
print('from the test')
"""
程序目录:
module_test.py
index.py
当前文件:
index.py
"""
# 另一个模块中的代码
import module_test as obj
#obj.test()
print(hasattr(obj,'test'))
getattr(obj,'test')()

浙公网安备 33010602011771号