博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
【python类】类
阅读量:6325 次
发布时间:2019-06-22

本文共 11510 字,大约阅读时间需要 38 分钟。

1. 类的命名空间

1> 简单变量和属性名称    1. 简单变量名(无点号):遵循函数LEGB作用域法则         ==> 赋值(X = value):// 使变量成为本地变量:除非声明是全局的         ==> 引用(X):// LEGB搜索变量     2. 属性名称(点号属性名称):遵循模块和类的规则         ==> 赋值(object.X = value)  // 实例对象命名空间内创建、修改变量         ==> 引用(object.X):// 基于类的对象:对象内遵循继承搜索;模块:对象中直接读取X(模块中存在类对象,模块没有继承的概念)    2> 命名空间组成:命名空间字典和命名空间链接        属性点号运算实际是内部字典的取值; // x.data = x.__dict__['data']        x.__dict__  // 获取实例的命名空间        x.__class__  // 获取实例的父类        sub.__bases__  //  sub类的父类        命名空间链接:当前命名空间找不到,会按照继承搜索查找        """        父类层次:        B: B --> A        F: F --> D --> B --> A --> C --> A --E         """        class A: pass        class B(A): pass        class C(A): pass        class D(B,C): pass        class E: pass        class F(D,E): pass

2. 继承

*继承原理:实际也是继承树的应用,子类实例总是先去查找自己的命名空间,然后才去查找父类命名空间*    class Manager(Person):   # 7 调用父类的构造函数:我们可以决定哪些参数使用父类,比如此处的Job             def __init__(self,name,pay):                     Person.__init__(self,name,'mgr',pay)             def givePay(self,percent,bouns=.10):       # 调用方法两种方式 1) 实例.方法() 2)类.方法(self) 不管哪种,方法都需要传递一个self调用                     Person.givePay(self,percent + bouns)   # 6.2 继承:扩展子类行为,只能在子类实例对象使用             def doSomething(self):                         return '[%s %s]' %(self.__class__.__name__,"考核")    """        # coding:utf-8        """        类的继承        """        class Employees:            def __init__(self,name,salary=0):                    self.name = name                    self.salary = salary            def givePay(self,percent):                    self.salary = self.salary + (self.salary * percent)            def work(self):                    print(self.name,"does stuff")            def __repr__(self):                    return "
" %(self.name,self.salary) class Chef(Employees): def __init__(self,name): Employees.__init__(self,name,50000) def work(self): print(self.name,'make foods') class Server(Employees): def __init__(self,name): Employees.__init__(self,name,40000) def work(self): print(self.name,'interfaces to customer') class PizzaRobbt(Chef): def __init__(self,name): Chef.__init__(self,name) def work(self): print(self.name,'make pizza') if __name__ == "__main__": # 一定要分清楚:object.attr 和 赋值 # 继承是从点号运算开始的,触发实例、类以及超类中属性搜索 bob = PizzaRobbt('bob') print(bob) bob.work() bob.givePay(0.2) print(bob) for kclass in Employees,Chef,Server,PizzaRobbt: # kclass.__name__ 是一个字符串 obj = kclass(kclass.__name__) obj.work() """ """ """ 类的组合:order下单包含Server、Customer、PizzaRobbt一起完成一件事情. """ from employees import Server,PizzaRobbt class Customer: def __init__(self,name): self.name = name def order(self,server): print(self.name,"order pizza",server) def pay(self,server): print(self.name,'pay money',server) class Oven: def bake(self): print('ovens bakes') class PizzaShop: def __init__(self): self.server = Server('Pat') self.chef = PizzaRobbt('bob') self.oven = Oven() def order(self,name): customer = Customer(name) customer.order(self.server) self.chef.work() self.oven.bake() customer.pay(self.server) if __name__ == "__main__": scene = PizzaShop() scene.order('tom') """

3. 抽象超类

*父类中的方法具体在子类中实现;抽象超类是不能被继承的,除非所有抽象方法都在子类实现*    """    class Super:             def method(self):                     print("in Super.method")             def delegate(self):                     self.action()       # 要是子类没有提供action,那么就会抛错:采用assert       # assert False,'action must be method!'     class Provider(Super):             def method(self):                    print('starting Sub.method')                    Super.method(self)  // 扩展父类的方法                    print('ending Sub.method')             def action(self):  // 实现父类的抽象方法                    print('In Provider.action')    """

4. 运算符重载

# coding:utf-8        """            运算符重载        """        import operator        class Number:        # 1. 拦截构造方法                def __init__(self,data):                        self.data = data        # 2. 拦截减法运算                def __sub__(self, other):                        return Number(self.data - other)        class Indexer:                def __init__(self,data):                        self.data = data                # 3.1 拦截索引、切片操作:实例对象拥有索引、切片操作                # 3.1 重载迭代:每次迭代实例对象时都会调用该方法,传入索引值                def __getitem__(self, item):                        print('getitem:',item)                        return self.data[item]                # 3.2 拦截索引赋值、切片赋值操作:实例对象拥有索引赋值、切片赋值操作                def __setitem__(self, key, value):                        self.data[key] = value        class Squeres:        """  iter() 迭代器工厂函数            __iter__() 迭代器协议,可以在自定义类里面形成迭代器 调用方式 1:手动next(i)调用    2:可迭代环境调用     可迭代对象:可以用迭代环境循环的对象    迭代器:支持迭代协议(也就是可以使用next调用);迭代器是可以记住状态的    可迭代对象不一定是迭代器 (for i in 'spam':)    迭代器一定是可迭代对象(支持在迭代环境循环调用)"""                def __init__(self,start,stop):                        self.value = start - 1                        self.stop = stop                # 3.3 在任何迭代环境中,会优先调用__iter__;之后调用__getitem__                # __iter__调用迭代协议;__getitem__调用索引取值,知道抛出索引超范                # __iter__ 根本没有重载索引表达式:X = Squeres(1,5) X[1] 报错                # __iter__ 只循环一次: X = Squeres(1,5) [for i in X] ==> 第二次迭代会为空                def __iter__(self):  # 定义了__iter__的方法,类实例是可迭代对象                        return self  # 此处返回self,每次生成的可迭代对象只能调用一次                def __next__(self):                        if self.value == self.stop:                                raise StopIteration                        self.value += 1                        return self.value            # 调用next方法            class SkipIterator:                    def __init__(self,wrapper):                            self.wrapper = wrapper                            self.offset = 0                    def __next__(self):                            if self.offset >= len(self.wrapper):                                    raise StopIteration                            item = self.wrapper[self.offset]                            self.offset += 2                            return item                # 返回迭代器对象                class SkipObject:                        def __init__(self,wrapper):                                    self.wrapper = wrapper                        def __iter__(self):                                    return SkipIterator(self.wrapper)            class Iter1:            """    1. 成员关系:contains(映射) --> iter --> getitem    2. __iter__和__getitem__ 都可捕获迭代环境      区别:1 __iter__ 使用迭代协议获取值(__next__),且可以保持状态信息;__getitem__ 使用索引获取值           2 __getitem__ 可以支持索引和切片操作           3 当字段索引行数据时(list、tuple),两者可替换;为hash类型时(dict、set),只能用__iter__"""                        def __init__(self,value):                                    self.value = value                        def __getitem__(self, item):                                    print("getitem:",item)                                    return self.value[item]                        def __iter__(self):                                    print("iter=>",end="")                                    self.offset = 0                                    return self                        def __next__(self):                                    print("next:",end="")                                    if self.offset == len(self.value):                                            raise StopIteration                                    item = self.value[self.offset]                                    self.offset += 1                                    return item                    def __contains__(self, item):                                    print("contanins: ",end='')                                    return item in self.value        class Library(object):                    def __init__(self):                                self.books = {'title': 'a', 'title2': 'b', 'title3': 'c', }                    def __getitem__(self, i):                                return self.books[i]                    def __iter__(self):                            # 方法1 使用生成器                            for titles in self.books:                                    yield self.books[titles]        class Empty:            """    拦截属性点号操作;    如果python可以在继承树(self.__dict__)找到该属性,那么__getattr__方法不会被调用    赋值:self.attr = value ==> self.__setattr__(attr,value)        """                    def __init__(self):                            self.data = 0                    def __getattr__(self, item):                            if item == "age":                                    print("__getattr__:",item,end=" ")                                    return 40                            else:                                    raise AttributeError(item)                    def __setattr__(self, key, value):                            if key == "data":                            # 此处一定用self.__dict__[key] = value                            # 因此在__setattr__里面赋值,会再调用__setattr__,造成内存溢出                                        self.__dict__[key] = value                            else:                                        raise AttributeError(key + "not allowed")            class A:            """    1.    __add__ 原处加法(a + b ;a += 1)    __radd__ 右侧加法    2.    a + b ,python会先去a里面找__add__,找不到会去__radd__查找    这个例子: b + a 会报错,因为python会先去B找__add__,然后去A找__radd__,均不满足    3. 每个二元运算符都支持:包括 __sub__(减法)"""                        def __init__(self,val):                                    self.val = val                        def __add__(self, other):                                    return self.val + other            class B:                        def __init__(self,val):                                    self.val = val                        def __radd__(self, other):                                    return self.val + other            class Callee:                """    编写api接口常用:可以将类和实例调用当作函数来使用,并且可以将实例的状态保留到函数内部,自然而然成为了被一个函数记住    ==>并调用另一个函数的实现    __call__ 任何定义了该方法的类和实例 支持与常规函数一致的调用    c = Callee()    c(1,2,3) ==> __call__ (1,2,3) {}"""                def __call__(self, *args, **kwargs):                            print("__call__,",args,kwargs)        class CallBack:                    def __init__(self,color):                            self.color = color                    def __call__(self):                            print('turn',self.color)    class BiJiao:"""比较:__lt__ __gt__ __cmp__(python3.0失效,使用operator替代)"""            pass    class Bool1:"""    拦截布尔操作    __bool__ >> __len__    python 3.0 优先尝试__bool__ python 2.6优先尝试__len__"""                def __bool__(self):                            return True

转载于:https://blog.51cto.com/kongxiaofa/2325065

你可能感兴趣的文章
Hadoop can't load native lib
查看>>
MyBatis学习总结(二)——使用MyBatis对表执行CRUD操作
查看>>
JavaScript学习总结(4)——JavaScript数组
查看>>
大型网站技术架构(八)网站的安全架构
查看>>
ubuntu下 验证码出不来问题 java.lang.Error: Probable fatal error:No fonts found.
查看>>
牙痛的特效治疗法
查看>>
eigrp的不等价负载均衡
查看>>
动态分区软件
查看>>
Java中用最有效率的方法算出2 乘以8 等於几?
查看>>
ASP.NET MVC路由(三)
查看>>
Oracle数据库之SQL---select之一
查看>>
曲线间平滑计算方法和一个Spline的实现
查看>>
网络优化-TCP和UDP的协作
查看>>
Android 常用动画
查看>>
IOS随记
查看>>
ASP.NET页面之间传递值的几种方式
查看>>
Linux系统权限
查看>>
TinyTemplate模板引擎火热出炉,正式开源了~~~
查看>>
android开发之GPS定位详解
查看>>
Mac OS X如何重装 苹果电脑重装操作系统
查看>>