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() # 会报错

################################################################################################################################################################################################################################################################################################################################################################################################################...............................................................................................................

posted @ 2019-05-04 20:12  猫神甜辣酱  阅读(443)  评论(0编辑  收藏  举报