【python类】类

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 "<Employees: name:%s,salary:%s>" %(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

原文地址:http://blog.51cto.com/kongxiaofa/2325065

时间: 2024-08-02 14:56:11

【python类】类的相关文章

[Python]剖析类的机理

Python是如何创建类的? 当python的解释器碰到类的定义的时候,它会像对待其他code一样先读取其内容,然后为这个class创建一个新的namespace并且执行其代码.类的定义通常包括变量,方法以及其他类.这些内容都在新的命名空间里面.从类的内容读到到类的对象的产生是通过内置type函数来实现,所以type函数也提供可动态创建类的可能. 用type函数动态创建类的时候,type这个构造函数需要三个参数,分别是类名,基类以及其属性. type实际上是一个元类,所谓的元类就是可以创建其他类

python Class(类) and Object Oriented(面向)

Python类与面向对象    程序=指令+数据 (或算法+数据结构).代码可以选择以指令为核心或以数据为核心进行编写.    两种范型        (1)以指令为核心:围绕"正在发生什么"进行编写(面向过程编程:程序具有一系列线性步骤:主体思想是代码作用于数据)以指令为中心,程序员的主要工作在于设计算法.        (2)以数据为核心:围绕"将影响谁"进行编写(面向对象编程<oop>:围绕数据及为数据严格定义的接口来组织程序,用数据控制对代码的访

Python 的类的下划线命名有什么不同?

1,以一个下划线开头的命名 ,如_getFile2,以两个下划线开头的命名 ,如__filename3,以两个下划线开头和结尾的命名,如 __init__()4,其它这些命名有什么不同吗 首先是单下划线开头,这个被常用于模块中,在一个模块中以单下划线开头的变量和函数被默认当作内部函数,如果使用 from a_module import * 导入时,这部分变量和函数不会被导入.不过值得注意的是,如果使用 import a_module 这样导入模块,仍然可以用 a_module._some_var

Python新式类和经典类的区别

@Python新式类和经典类的区别 class ClassicClass(): pass class NewStyleClass(object): pass x1 = ClassicClass() x2 = NewStyleClass() print x1.__class__, type(x1) print x2.__class__, type(x2) 输出结果: __main__.ClassicClass <type 'instance'> <class '__main__.NewSt

谨慎修改Python的类属性

Python的类和类实例都是可变对象,可以随时给属性赋值,并且在原处修改. 在对类属性进行修改时需要特别小心,因为所有的类实例都继承共享类属性,除非实例本身存在和类属性同名的属性.对类属性进行修改,会影响到所有由这个类生成的实例. class CA(object): cls_pre = 'aaaaa' def __init__(self): self.obj_pre = 'bbbbb' a = CA() b = CA() print(a.cls_pre, a.obj_pre) print(b.c

python元类分析

刚开始接触到Python新式类中的元类的概念的时候很是纠结了下..不知道这是个啥东西... 用以下几个定义来说明吧: (1)Python中,类也是对象..只不过这种对象比较的特殊,他用于创建别的对象 (2)元类也是一种类,只不过它更特殊...他是用来创建别的类的类...(呵呵,是不是很拗口) 先来看一段代码吧: class Fjs(object): def __init__(self, name): self.name = name def hello(self): print "hello b

python 定制类

看到类似__slots__这种形如__xxx__的变量或者函数名就要注意,这些在Python中是有特殊用途的. __slots__我们已经知道怎么用了,__len__()方法我们也知道是为了能让class作用于len()函数. 除此之外,Python的class中还有许多这样有特殊用途的函数,可以帮助我们定制类. __str__ 我们先定义一个Student类,打印一个实例: >>> class Student(object): ... def __init__(self, name):

Python的类与类型

1.经典类与新式类 在了解Python的类与类型前,需要对Python的经典类(classic classes)与新式类(new-style classes)有个简单的概念. 在Python 2.x及以前的版本中,由任意内置类型派生出的类(只要一个内置类型位于类树的某个位置),都属于“新式类”,都会获得所有“新式类”的特性:反之,即不由任意内置类型派生出的类,则称之为“经典类”. “新式类”和“经典类”的区分在Python 3.x之后就已经不存在,在Python 3.x之后的版本,因为所有的类都

Python -- str 类

Python str类常用方法: class str(object): def capitalize(self):   # 全部字母变小写只有首字母变大写: >>> test = 'PYTHON' >>> test.capitalize() 'Python' def casefold(self): # 全部字母变小写: >>> test = 'PYTHON' >>> test.casefold() 'python' def cente

Python -- list 类

Python list类常用方法 class list(object): def append(self, p_object): # 向列表中添加元素: >>> name_list ['shuoming', 'python', 'search'] >>> name_list.append("python") >>> name_list ['shuoming', 'python', 'search', 'python'] def cl