python(二)面向对象知识点
模块
别名
import my_module as xxx(别名)
先导入内置模块
再导入第三方模块
再导入自定义模块
from my_module(导入的文件) import *(变量)
__all__ 能够约束*导入的变量的内容
# 在导入的文件里写 __all__=['name']
from my_module import name(要导入的变量)
* 模块之间不能循环引用
* 已经导入的模块发生修改,是不会被感知到的
* 要想修改的模块正在运行中的程序感知到,重启这个程序
一个文件中的__name__变量
* 当这个文件被当作脚本执行的时候 __name__=='__main__'
if __name__ == '__main__':
# 代码
* 当这个文件被当作模块导入的时候 __name__=='模块的名字'
包: 文件夹中有一个__init__.py文件
包: 是几个模块的集合
从包中导入模块
目录结构
glance
----api
----__init__.py
----policy.py
#绝对导入
# 在执行一个py脚本的时候,这个脚本以及和这个脚本同级模块中只能用绝对导入
import glance.api.policy as policy
policy.get() #别名导入
import glance.api import policy
policy.get()
# 相对导入
# 含有相对导入的文件不能被直接执行
from . import policy
python中支持两种编程方式
# 面向对象
# 函数式编程
定义
class 类名:
def __init__(self): # 该方法自动执行
pass
def 函数名(self):
pass
x1=类名() # 创建了一个对象/实例化一个对象
x1.函数名()
构造方法
class Foo:
def __init__(self,name):
self.name=name
self.age=18
obj=Foo('张三')
#-----------
class UserInfo:
def func1(self):
print('func1')
self.func2()
def func2(self):
print('func2')
obj=UserInfo()
obj.func1()
#------
在指定类中编写和当前类相关的所有代码+提取公共
class Person:
def __init__(self,na,gen,age,fig):
self.name=na
self.gender=gen
self.age=age
self.fight=fig
def grassland(self):
self.fight=self.fight-10
def practice(self):
self.fight=self.fight+10
dong=Person('张三','女',12,400)
面向对象三大特性:封装/继承/多态
封装
将相关的功能封装到一个类中
class Message:
def email(self):pass
def msg(self):pass
将数据分装到一个对象中
class Person:
def __init__(self,name,age):
self.name=name
self.age=age
obj=Person('xiaoming',12)
继承
class SuperBase: # 父类,基类
pass
class Base(SuperBase):# 子类,派生类
pass
就近原则
多继承(先找左/再找右)
class Base1:
pass
class Base2:
pass
class Foo(Base1,Base2):
pass
self 是那个类的对象,那么就从该类开始找(自己没有就找父类)
* 特点提高代码的复用性
多态
多种形态,对传的参数没有要求,支持多种类型,所有默认支持多态
类的成员
- 变量(字段)
- 实例变量(字段)
- 类变量(静态字段)
class Foo:
# 类变量
country='中国'
def __init__(self,name):
# 实例变量
self.name=name
准则
* 实例变量(字段)访问时,使用对象访问
* 类变量(静态字段)访问是,使用类方法访问
什么时候用类变量
当所有对象中有共同的字段是,且要改都改要删都删时,可以把实例变量改成类变量
私有变量
__name
class Foo:
__country="zhongguo" #私有类变量
def __init__(self,name):
self.__name=name
def func(self):
print(self.__name)
# 静态方法
* 编写时:
-方法上方写 @staticcmethod
-方法参数可有可无
* 调用时
-类.方法名() *
-对象.方法名()
* 如果方法无需使用对象中分装的值,那么就可以使用静态方法
class Foo:
def __init__(self, name):
self.__name = name
# 实例方法
def func1(self):
print(self.__name)
# 静态方法,如果方法无序使用对象中封装的值,那么就可以使用静态方法
@staticmethod
def display():
print('555')
# 类方法
@classmethod
def show(cls,x1,x2):# cls 是类(就是把这个类作为参数传到里面)
print(cls,x1,x2)
obj=Foo('张三')
obj.func1()
Foo.display()
# 执行类方法
Foo.show(1,8)
# 类方法
> 定义时
- 方法上写 @classmethod
- 方法的参数: 至少有一个cls参数
> 执行时
- 类名.方法() # 默认会将当前类传到参数中
> 什么时候用
- 方法中用到了当前类
属性
> 编写时
- 方法上写 @property
- 方法参数:只有一个self
> 调用时:无序加括号 对象.方法
> 应用场景:对于简单的方法,当无序传参的时候
@property
class Foo:
def __init__(self, name):
self.__name = name
# 属性
@property
# def __func1(self) #私有属性
def func1(self):
return 1
obj=Foo()
print(obj.func1)
组合
class Stark:
def __init__(self,num):
self.num=num
def changelist(self,request):
print(self.num,request)
class Role(Stark):
pass
config_obj_list=[Stark(1),Stark(2),Stark(3)]
for item in config_obj_list:
print(item.changelist(120))
# 主动调用其他类的成员
class Base:
def f1(self):
print('3个功能')
class Foo(object):
def f1(self):
print('5个功能')
Base.f1(self) #主动调用其他类的成员
obj=Foo()
obj.f1()
# 第二种
class Base:
def f1(self):
print('3个功能')
class Foo(Base):
def f1(self):
print('5个功能')
super().f1() # 按照父类的继承顺序找
特殊成员
class Foo:
def __init__(self, a1, a2):
self.a1 = a1
self.a2 = a2
def __call__(self, *args, **kwargs):
print(111,args,kwargs)
def __getitem__(self, item):
print(item)
def __setitem__(self, key, value):
print(key,value)
def __delitem__(self,key):
print(key)
def __add__(self,other):
return self.a1+other.a2
# 类名() 自动调用 __init__
obj=Foo(1,2)
# 对象() 自动执行 __call__
obj(5,12,12,31)
type() #查看类型
# 对象[] 自动执行 __getitem__
obj['yu']
# 对象['xx]=11 自动执行 __setitem__
obj['xxx']='ggg'
# del 对象['xx] 自动执行__delitem__
# 对象+对象 自动执行 __add__
obj=Foo(1,2)
obj2=Foo(55,33)
ret=obj2+obj
print(ret) # 55+2
# with 对象 自动执行 __enter__/__exit__
class Foo:
def __init__(self, a1, a2):# 初始化
'''
对空对象进行数据初始化
'''
def __new__(cls, *args, **kwargs): # 构造方法
'''
创建一个空对象
'''
obj=Foo(1,2)
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
__dict__ 把参数以字典的形式打印出来
obj = Foo('ximing',33)
obj1=Foo('xiaohua',12)
print(obj.__dict__)
print(obj1.__dict__)
__iter__ 可迭代对象
issubclass/type/isinstance
issubclass(a,b) #检查第一个参数是否是第二个参数的 子子孙孙类
class Foo:
def __init__(self, name, age):
self.name = name
self.age = age
obj=Foo('张三',12)
print(type(obj)==Foo) # True 获取当前对象是由那个类创建的
isinstance(obj,Foo) # 检查第一个参数是否是第二个参数(类及父类)的实例
判断是否被调用
callable(obj)
方法和函数
类,方法
外,函数
对象.xxx--->xxx就是方法
类.xxx --->xxx就是方法
xxx ----> xxx就是函数
打印查看
function
method
反射
v=getattr(obj,'func')
# 根据字符查为参数(第二个参数),去对象(第一个参数)中寻找与之同名的成员
class Account(object):
func_list = ['login', 'logout', 'register']
def login(self):
print('登录')
def logout(self):
print('注销')
def register(self):
print('注册')
def run(self):
print('请输入要执行的功能:'
'0:登录'
'1:注销'
'2:注册')
choice=int(input("请输入要执行的序号"))
func_name=Account.func_list[choice]
func=getattr(self,func_name)
func()
obj=Account()
obj.run()
hasattr #根据字符串的形式,去判断对象是否有成员
setattr # 设置一个成员
delattr # 删除一个成员
类的约束
class BaseMessage:
def send(self):
# 必须继承BaseMessage 然后其中必须编写send方法,用于完成具体业务逻辑
raise NotImplementedError('.send() 必须被重写')
class Email(BaseMessage):
pass
obj=Email()
obj.send() # 会报错
################################################################################################################################################################################################################################################################################################################################################################################################################...............................................................................................................
决定自己的高度的是你的态度,而不是你的才能
记得我们是终身初学者和学习者
总有一天我也能成为大佬