zoukankan      html  css  js  c++  java
  • python 面向对象

    1、面向对象的基本知识

    • 面向对象是一种编程方式,此编程方式的实现是基于对   对象 的使用
    • 是一个模板,模板中包装了多个函数供使用(可以讲多函数中公用的变量封装到对象中)
    • 对象,根据模板创建的实例(即:对象),实例用于调用被包装在类中的函数
    • 面向对象三大特性:封装、继承和多态

    2、类的成员

    类的成员可以分为三大类:字段、方法和属性(1、字段:普通字段、静态字段;2、方法:普通方法、类方法、静态方法;3、属性:普通属性)

    所有成员中,只有普通字段的内容保存对象中,即:根据此类创建了多少对象,在内存中就有多少个普通字段。而其他的成员,则都是保存在类中,即:无论对象的多少,在内存中只创建一份。

     2.1、字段

    字段包括:普通字段和静态字段,他们在定义和使用中有所区别,而最本质的区别是内存中保存的位置不同,

    • 普通字段 属于 对象
    • 静态字段 属于 
      class Province:
          # 静态字段
          country ='中国'
          def __init__(self, name):
              # 普通字段
              self.name = name
      # 直接访问普通字段
      obj = Province('河北省')
      print(obj.name)
      # 直接访问静态字段
      print(Province.country)
      print(obj.country)
      
    • 静态字段在内存中只保存一份
    • 普通字段在每个对象中都要保存一份

    应用场景: 通过类创建对象时,如果每个对象都具有相同的字段,那么就使用静态字段

     2.2、方法

    方法包括:普通方法、静态方法和类方法,三种方法在内存中都归属于类,区别在于调用方式不同。

    • 普通方法:由对象调用;至少一个self参数;执行普通方法时,自动将调用该方法的对象赋值给self
    • 类方法:由调用; 至少一个cls参数;执行类方法时,自动将调用该方法的复制给cls
    • 静态方法:由调用;无默认参数;
    class Foo:
        def __init__(self, name):
            self.name = name
    
        def ord_func(self):
            """ 定义普通方法,至少有一个self参数 """
            # print self.name
            print('普通方法')
    
        @classmethod
        def class_func(cls):
            """ 定义类方法,至少有一个cls参数 """
            print('类方法')
    
        @staticmethod
        def static_func():
            """ 定义静态方法 ,无默认参数"""
    
            print('静态方法')
    
    
    # 调用普通方法
    f = Foo(11)
    f.ord_func()
    # 调用类方法
    Foo.class_func()
    # 调用静态方法
    Foo.static_func()

    相同点:对于所有的方法而言,均属于类(非对象)中,所以,在内存中也只保存一份。

    不同点:方法调用者不同、调用方法时自动传入的参数不同。

    2.3、属性

    Python中的属性其实是普通方法的变种。 

    2.3.1、属性的基本使用

     由属性的定义和调用要注意以下几点:

    • 定义时,在普通方法的基础上添加 @property 装饰器;
    • 定义时,属性仅有一个self参数
    • 调用时,无需括号
                 方法:foo_obj.func()
                 属性:foo_obj.prop

    注意:属性存在意义是:访问属性时可以制造出和访问字段完全相同的假象

             属性由方法变种而来,如果Python中没有属性,方法完全可以代替其功能。

    class Foo:
    
        def func(self):
            pass
    
        # 定义属性
        @property
        def prop(self):
            pass
    
    foo_obj = Foo()
    
    foo_obj.func()
    foo_obj.prop   #调用属性  

    实例:对于主机列表页面,每次请求不可能把数据库中的所有内容都显示到页面上,而是通过分页的功能局部显示,所以在向数据库中请求数据时就要显示的指定获取从第m条到第n条的所有数据(即:limit m,n),这个分页的功能包括:

    • 根据用户请求的当前页和总数据条数计算出 m n
    • 根据m n 去数据库中请求数据 
    class Pages:
        def __init__(self, current_page):
            # 用户当前请求的页码(第一页、第二页...)
            self.current_page = current_page
            # 每页默认显示10条数据
            self.per_items = 10
        @property
        def start(self):
            val = (self.current_page - 1) * self.per_items
            return val
    
        @property
        def end(self):
            val = self.current_page * self.per_items
            return val
    p = Pages(2)
    print(p.start)
    print(p.end) 

    从上述可见,Python的属性的功能是:属性内部进行一系列的逻辑计算,最终将计算结果返回

    2.3.2、属性的两种定义方式

    属性的定义有两种方式:

    • 装饰器 即:在方法上应用装饰器
    • 静态字段 即:在类中定义值为property对象的静态字段

    装饰器方法:

    class Goods(object):
    
        def __init__(self):
            # 原价
            self.original_price = 100
            # 折扣
            self.discount = 0.8
    
        @property
        def price(self):
            # 实际价格 = 原价 * 折扣
            new_price = self.original_price * self.discount
            return new_price
    
        @price.setter
        def price(self, value):
            self.original_price = value
    
        @price.deleter
        def price(self, value):
            del self.original_price
    
     obj = Goods()
     print(obj.price)         # 获取商品价格
     obj.price = 200   # 修改商品原价
     print(obj.price)
     del obj.price     # 删除商品原价
    
     print(obj.price)  

    静态字段方法

    class Foo:
    
        def get_bar(self):
            return 'Hello'
    
        BAR = property(get_bar)
    
    obj = Foo()
    reuslt = obj.BAR        # 自动调用get_bar方法,并获取方法的返回值
    print(reuslt) 

    property的构造方法中有个四个参数

    • 第一个参数是方法名,调用 对象.属性 时自动触发执行方法
    • 第二个参数是方法名,调用 对象.属性 = XXX 时自动触发执行方法
    • 第三个参数是方法名,调用 del 对象.属性 时自动触发执行方法
    • 第四个参数是字符串,调用 对象.属性.__doc__ ,此参数是该属性的描述信息

    由于静态字段方式创建属性具有三种访问方式,我们可以根据他们几个属性的访问特点,分别将三个方法定义为对同一个属性:获取、修改、删除 

    class Goods(object):
    
        def __init__(self):
            # 原价
            self.original_price = 100
            # 折扣
            self.discount = 0.8
    
        def get_price(self):
            # 实际价格 = 原价 * 折扣
            new_price = self.original_price * self.discount
            return new_price
    
        def set_price(self, value):
            self.original_price = value
    
        def del_price(self, value):
            del self.original_price
    
        PRICE = property(get_price, set_price, del_price, '价格属性描述...')
    
    obj = Goods()
    obj.PRICE         # 获取商品价格
    obj.PRICE = 200   # 修改商品原价
    del obj.PRICE     # 删除商品原价
    

    3、类成员的修饰符

    类的所有成员在上一步骤中已经做了详细的介绍,对于每一个类的成员而言都有两种形式:

    • 公有成员,在任何地方都能访问(私有成员命名时,前两个字符是下划线。)
    • 私有成员,只有在类的内部才能访问。
    class C:
    
        def __init__(self):
            self.name = "公有字段"
            self.__foo = "私有字段"

    静态字段

    • 公有静态字段:类可以访问;类内部可以访问;派生类中可以访问
    • 私有静态字段:仅类内部可以访问;

    普通字段

    • 公有普通字段:对象可以访问;类内部可以访问;派生类中可以访问
    • 私有普通字段:仅类内部可以访问;

    ps:如果想要强制访问私有字段,可以通过 【对象._类名__私有字段明 】访问(如:obj._C__foo),不建议强制访问私有成员。

    class C:
        dic = "静态公有字段"
        _iso = "静态私有字段"
        def __init__(self):
            self.name = "公有字段"
            self.__foo = "私有字段"
    
        def func(self):
            print(self.__foo)    # 类内部访问
    
    
    class D(C):
        def show(self):
            print(self.__foo)   #派生类中访问
    
    obj = C()
    print(obj._C__foo )         # 通过对象访问
    obj.func()                  # 类内部访问
    obj_son = D()
    obj_son.show()              # 派生类中访问
    

     

    4、类的特殊成员 

      Python的类成员以及成员修饰符,从而了解到类中有字段、方法和属性三大类成员,并且成员名前如果有两个下划线,则表示该成员是私有成员,私有成员只能由类内部调用。无论人或事物往往都有不按套路出牌的情况,Python的类成员也是如此,存在着一些具有特殊含义的成员,详情如下:

      1、 __doc__

        表示类的描述信息

     

     

      2、__module__  __class__ 

     

        __module__ 表示当前操作的对象在那个模块

     

        __class__     表示当前操作的对象的类是什么

     

     

      3、 __init__

     

        构造方法,通过类创建对象时,自动触发执行。

     

     

      4、 __del__

     

        析构方法,当对象在内存中被释放时,自动触发执行。

     

        注:此方法一般无须定义,因为Python是一门高级语言,程序员在使用时无需关心内存的分配和释放,因为此工作都是交给Python解释器来执行,所以,析构函数的调用

        是由解释器在进行垃圾回收时自动触发执行的。

     

     

      5、 __call__

     

        对象后面加括号,触发执行。

     

        注:构造方法的执行是由创建对象触发的,即:对象 = 类名() ;而对于 __call__ 方法的执行是由对象后加括号触发的,即:对象() 或者 类()()

     

     

      6、__dict__

     

        类或对象中的所有成员

     

        上文中我们知道:类的普通字段属于对象;类中的静态字段和方法等属于类,即:

     

     

       7. __str__

     

        如果一个类中定义了__str__方法,那么在打印 对象 时,默认输出该方法的返回值。

     

     

      8__getitem____setitem____delitem__

     

        用于索引操作,如字典。以上分别表示获取、设置、删除数据

     

     

      9__getslice____setslice____delslice__

     

         该三个方法用于分片操作,如:列表

    class Foo(object):
     
        def __getslice__(self, i, j):
            print('__getslice__',i,j)
     
        def __setslice__(self, i, j, sequence):
            print('__setslice__',i,j)
     
        def __delslice__(self, i, j):
            print('__delslice__',i,j)
     
    obj = Foo()
     
    obj[-1:1]                   # 自动触发执行 __getslice__
    obj[0:1] = [11,22,33,44]    # 自动触发执行 __setslice__
    del obj[0:2]                # 自动触发执行 __delslice__
    

     

      

      10. __iter__ 

      用于迭代器,之所以列表、字典、元组可以进行for循环,是因为类型内部定义了 __iter__ 

     

      

      11. __new__  __metaclass__

     5、函数参数

    函数参数说明:

      位置形参,星号元组形参,命名关键字形参,双星号字典形参和缺省形参可以混合使用

    函数参数前后顺序:

      位置参数,星号元组参数,命名关键字形参,双星号字典形参 

  • 相关阅读:
    动态生成 Excel 文件供浏览器下载的注意事项
    JavaEE 中无用技术之 JNDI
    CSDN 泄露用户密码给我们什么启示
    刚发布新的 web 单点登录系统,欢迎下载试用,欢迎提建议
    jQuery jqgrid 对含特殊字符 json 数据的 Java 处理方法
    一个 SQL 同时验证帐号是否存在、密码是否正确
    PostgreSQL 数据库在 Windows Server 2008 上安装注意事项
    快速点评 Spring Struts Hibernate
    Apache NIO 框架 Mina 使用中出现 too many open files 问题的解决办法
    解决 jQuery 版本升级过程中出现 toLowerCase 错误 更改 doctype
  • 原文地址:https://www.cnblogs.com/mainstream/p/11315329.html
Copyright © 2011-2022 走看看