python从入门到放弃

Python基础(四)

2018-02-12  本文已影响64人  EvanForEver

关于类与对象操作的BIFs

  1. type() 返回对象类型
  2. id(),查看对象id
  3. dir(),查看对象下变量及函数
  4. issubclass(),isinstance(), super(),类,实例,调父类
  5. hasattr(),getattr(),setattr(),delattr()类属性操作
  6. globals(),locals(),全局与局部的名称空间
  7. import(),reload(),模块的导入与重载

面向对象编程OOP

1.比较编程方式
 面向过程:根据业务逻辑从上到下写垒代码
 函数式:将某功能代码封装到函数中,日后便无需重复编写,仅调用函数即可,函数是对面向过程的一次封装
 面向对象:对函数进行分类和封装,让开发“更快更好更强…”,面向对象是更高一层的封装
2.OOP的核心思想:
 类:从近似的对象中抽象出类
 对象:然后再从类出实例化出对象

类的创建与实例化

创建类

  1. class关键字
  2. 指定继承
  3. 定义类的成员
    数据成员
     类变量
     实例变量
    方法成员
     类方法
     实例方法

实例化类

class Student():
    #类变量
    student_total=0
    student_list=[]
    student_graduated=0
    pass_score=1000
    #魔法函数创建实例变量
    def __init__(self,name,age,gender):
        self.name=name
        self.age=age
        self.gender=gender
        self.__score=0
        Student.student_total+=1
        Student.student_list.append(name)
     #实例方法
    def exam(self,score):
        if score<60:
            return 'sorry, You have failed this time,better luck next time'
        else:
            self.__score+=score
            str1='Good!, Your score is now'+str(self.__score)
        
        if self.__score>=Student.pass_score:
            Student.student_graduated+=1
        return str1
    
    def check(self,):
        if self.score<Student.pass_score:
            return 'You have',Student.pass_score-self.score,' scores to archive!'
        else:
            return 'You have graduated from julyedu.com'
    #类方法
    @classmethod
    def get_student_graduated(cls,):
        return Student.student_graduated
    
    @classmethod
    def get_student_list(cls,):
        return Student.student_list    
    #普通方法
    @staticmethod
    def static1():
        return 'it can be called by both the instance and the class'

xiaohong=Student('xiaohong',23,'female')

xm=Student('xiaoming',22,'male')

xm.exam(99)

类的内部结构

OOP三大特性总结

#继承时在括号中加父类名字
>>class list1(list):
>>     name='this is list1 class'
>>     #__name如果使用前双划,属性将被隐藏
>>issubclass(list1,list) #判断list1是不是list的子类
True

>>class person():
>>   def speak(self,):
>>        return 'people can speak language!'
>>    def work(self,):
>>        print('people should have work to do!')

>>class fireMan(person):
>>    def work(self,):
>>        print('A great work that can save people!')
>>    def speak2(self,):
>>        print(super().speak(),'FireMan needs to speak loudly!')

>>fireman1=fireMan()
>>fireman1.work()#多态,子类方法覆盖父类方法
>>fireman1.speak2()#super方法调用父类
A great work that can save people!
people can speak language! FireMan needs to speak loudly!

访问控制

Python没有像其它语言有访问控制的关键字,例如private、protected等等。Python通过命名约定来实现的访问控制,例如在之前Student类的基础上,对其进行数据的保护。便其数据不能再被通过类名.或对象.的形式被调用。
 对模块级的控制,通过在标识符前加单下划线_实现。
 对类内部的属性及方法,通过在在标识符前加双下划线__来实现的私有化
 类中两个双下划线包裹的属性或方法为特殊

魔法方法Magic Method

案例

#构造和初始化魔术
>>class myclass():
>>    def __init__(self,):
>>        print('被__init__')

>>    def __del__(self,):
>>        print('我被__del__了,再见')        
>>c1=myclass()
被__init__
>>del c1
我被__del__了,再见
比较魔术 作用
__cmp__(self, other) 是最基本的用于比较的魔术方法。实现了所有的比较符号
__eq__(self, other) 定义了等号的行为, == 。
__ne__(self, other) 定义了不等号的行为, != 。
__lt__(self, other) 定义了小于号的行为, < 。
__gt__(self, other) 定义了大于等于号的行为, >= 。
数值处理魔法
__pos__(self) 实现正号的特性(比如 +some_object)
__neg__(self) 实现负号的特性(比如 -some_object)
__abs__(self) 实现内置 abs() 函数的特性。
__invert__(self) 实现 ~ 符号的特性。
__add__(self, other) 实现加法。
__sub__(self, other) 实现减法。
__mul__(self, other) 实现乘法。
__floordiv__(self, other) 实现 // 符号实现的整数除法。
__div__(self, other) 实现 / 符号实现的除法。
__truediv__(self, other) 实现真除法。
__iadd__(self, other) 实现赋值加法+=
容器魔法
__len__(self) 定义当被 len() 调用时的行为(返回容器中元素的个数)
__getitem__(self, key) 定义获取容器中指定元素的行为,相当于 self[key]
__setitem__(self, key, value) 定义设置容器中指定元素的行为,相当于 self[key] = value
__delitem__(self, key) 定义删除容器中指定元素的行为,相当于 del self[key]
__iter__(self) 定义当迭代容器中的元素的行为
__reversed__(self) 定义当被 reversed() 调用时的行为
__contains__(self, item) 定义当使用成员测试运算符(in 或 not in)时的行为
反射 通过魔术方法控制使用 isinstance() 和 issubclass() 内置方法的反射行为。
__instancecheck__(self, instance) 检查一个实例是不是你定义的类的实例
__subclasscheck__(self, subclass) 检查一个类是不是你定义的类的子类
调用
__call__(self, [args...]) 允许一个类的实例像函数一样被调用,即x() 与 x.__call__() 是相同的. __call__ 参数可变。这意味着你可以定义 __call__ 为其他你想要的函数,无论有多少个参数

案例

#比较魔术
class myclass():
    def __init__(self,num):
        self.num=num
        print('被__init__')  
        
    def __eq__(self,other):
        if type(other)==int:
            return True if self.num>other else False                
        else:
            print('can\'t compare with other datatype except int',)

>>c1=myclass(3)
被__init__
>>c1=='china'
cant compare with other datatype except int

#数值处理魔法
>>class myclass():
    def __init__(self,num):
        self.num=num
        print('被__init__')
        
    def __pos__(self):
        self.num=10086

>>c1=myclass(-3)
被__init__
>>+c1
>>c1.num
10086

#类表现魔法
class myClass():
    __doc__='this is myClass docuemtnt'# 表示类的描述信息,重写代表自定义描述
    __name__='moduel name is V'#模块是对象,并且所有的模块都有一个内置属性 __name__。
#一个模块的 __name__ 的值取决于如何应用模块。
#如果 import 一个模块,那么模块__name__ 的值通常为模块文件名,不带路径或者文件扩展名。
#但是也可以像一个标准的程序样直接运行模块.
#在这种情况下, __name__ 的值将是一个特别缺省"__main__"。上述类中加上__name__ == '__main__'的判断语句
#可以直接在终端环境下执行python dirfile.py /tmp进行测试,不必非得在交互式环境下导入模块进行测试。

#容器魔法
class FunctionalList():

    def __init__(self, values=None):#初始化
        if values is None:
            self.values = []
        else:
            self.values = values

    def __len__(self):
        return len(self.values)+10#故意多加10个

    def __getitem__(self, key):
        if type(key)==slice:#如果传入的key是一个slice类,则这是一个切片访问
            start=key.start
            stop=key.stop+1
            if key.stop==None:
                stop=-1
            if key.start==None:
                start=0
            return self.values[start:stop]
        else:
            return str(self.values[key])*2#故意多输出2次
    

    def __setitem__(self, key, value):
        self.values[key] = str(value)+'haha'#故意都给转成str,再加haha字样

    def __delitem__(self, key):
        pass
        #del self.values[key]#就是故意不去删

    def __iter__(self):
       #用于迭代器,之所以列表、字典、元组等可以进行for循环,是因为类型内部定义了 __iter__
       # pass
        return iter(self.values)

    def __reversed__(self):
        return reversed(self.values)


    def append(self, value):#非魔术方法
        self.values.append(value)

>>l1=list(range(10))
>>o1=FunctionalList(l1)
>>len(o1)#调用的是__len__
20
>>o1[0:9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

#调用
>>class callableInstance():

    def __init__(self, x, y):
        self.x, self.y = x, y

    def __call__(self,):
        self.x, self.y = self.y, self.x
        #调用时交换对象
    
>>c1=callableInstance(1,5)# 执行 __init__,赋值x,y
>>print(c1.x,c1.y)
1 5
>>c1()# 执行 __call__,交换变量变换
>>print(c1.x,c1.y)
5 1

模块module

  1. 模块定义:一个.py文件,包含了对象定义与语句
  2. 模块作用:用来从逻辑上组织代码
  3. 模块使用:

包package

  1. 包定义:
     含有init.py文件夹被称为包, init.py文件用于标识当前文件夹是一个包。
    (该文件可以为空,但必须有)
    包用于组织模块,通常把功能相近的模块进行再次封装成为包。
  2. 包的目录结构:
     模块
     子包
     (子包下的子包)
  3. 包的安装(pip,conda)
  4. 不同的导入方式(假设包名为test)
     import test#导入init.py这个moduel。
     from test import *#导入init.py这个moduel下所有对象导入到当前空间。
     from test.test_level1.test_level2 import test_level2#导入的层次目录下的模块。
    还是模块
上一篇 下一篇

猜你喜欢

热点阅读