精华内容
下载资源
问答
  • Python的高级特性1-7...,对象,实例,方法几个面向对象的几个基本概念,其实我觉得很多人并不真正了解这一块。 举个例子进行测试一下: In [19]: class A(): ....: pass ....: In [20]: a = A In...

    Python的高级特性1-7系列是本人从Python2过渡3时写下的一些个人见解(不敢说一定对),接下来的系列主要会以类级为主。

    类,对象,实例,方法是几个面向对象的几个基本概念,其实我觉得很多人并不是真正了解这一块。

    举个例子进行测试一下:

    In [19]: class A():
       ....:     pass
       ....: 
    
    In [20]: a = A
    
    In [21]: type(a)
    Out[21]: classobj
    
    In [22]: class B(object):
       ....:     pass
       ....: 
    
    In [23]: b = B
    
    In [24]: type(b)
    Out[24]: type
    
    In [25]: c = A()
    
    In [26]: type(c)
    Out[26]: instance
    
    In [27]: d = B()
    
    In [28]: type(d)
    Out[28]: __main__.B

    你能解释清楚a,b,c,d以及A,A(),B,B()真正代表什么吗?

    如果可以的话,下面的东西就不用看了。

    讲解的话用另一个例子吧,因为上述例子没有涉及到方法,不方便展开。

    In [79]: %cpaste
    Pasting code; enter '--' alone on the line to stop or use Ctrl-D.
    :class A:
    :       def __init__(self,name):
    :               self.name = name
    :       def say(self):
    :               return("I am %s" % (self.name))
    :    
    :a1 = A
    :a2 = A("alex")
    :--
    
    In [80]: dir(a1)
    Out[80]: ['__doc__', '__init__', '__module__', 'say']
    
    In [81]: dir(a2)
    Out[81]: ['__doc__', '__init__', '__module__', 'name', 'say']

    在这个例子中,a1和A是一个类,self代表一个对象,a2与A("alex")代表一个实例,say()代表方法。可以看到a1这个类本身是不含name属性的,但有方法属性(ps:这里必须补充一点,如果有类属性“xx”,那么a1的属性列表里是会有“xx”的);a2是一个实例,则有name属性;self是一个对象,因为不好测量,所以很多人模糊地认为对象就是实例,其实正确说来,对象一个模板,而实例就是这个模板的具体实现,详细地说,self包含name和say()的属性和方法,而a2包含name 为 alex以及say()方法;方法的话就不用细说了,这个大家一般不会混淆。

    现在看第一个例子就会觉得豁然开朗了吧,除了一个type(A)为什么是type,这个涉及到metaclass,后续再说,不是本节重点。

    转载于:https://www.cnblogs.com/alexkn/p/4667186.html

    展开全文
  • 这么做的意义在于归一化,什么叫归一化,就是只要基于同一个接口实现的类,这些类都应当实现接口类的定义的接口方法。# java : 面向对象编程# 设计模式 —— 接口# 接口类 : python原生不支持# 接口类不可以实例...

    1. 接口类

    接口提取了一群类共同的函数,可以把接口当做一个函数的集合。

    然后让子类去实现接口中的函数。

    这么做的意义在于归一化,什么叫归一化,就是只要是基于同一个接口实现的类,这些类都应当实现接口类的定义的接口方法。

    # java : 面向对象编程

    # 设计模式 —— 接口

    # 接口类 : python原生不支持

    # 接口类不可以实例化

    from abc import abstractmethod,ABCMeta

    class Payment(metaclass=ABCMeta): # 元类 默认的元类 type

    @abstractmethod

    def pay(self,money):pass # 没有实现这个方法

    # 规范 :接口类可以

    class Wechat(Payment):

    def pay(self,money):

    print("已经用微信支付了%s元"%money)

    class Alipay(Payment):

    def pay(self,money):

    print("已经用支付宝支付了%s元" % money)

    class Applepay(Payment):

    def pay(self,money):

    print("已经用applepay支付了%s元" % money)

    def pay(pay_obj,money): # 统一支付入口

    pay_obj.pay(money)

    # wechat = Wechat()

    # ali = Alipay()

    app = Applepay()

    # wechat.pay(100)

    # ali.pay(200)

    p = Payment()

    2.  与java一样,python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类,它的特殊之处在于只能被继承,不能被实例化。

    #一切皆文件

    import abc #利用abc模块实现抽象类

    class All_file(metaclass=abc.ABCMeta):

    all_type="file"

    @abc.abstractmethod #定义抽象方法,无需实现功能

    def read(self):

    "子类必须定义读功能"

    with open("filaname") as f:

    pass

    @abc.abstractmethod #定义抽象方法,无需实现功能

    def write(self):

    "子类必须定义写功能"

    pass

    class Txt(All_file): #子类继承抽象类,但是必须定义read和write方法

    def read(self):

    print("文本数据的读取方法")

    def write(self):

    print("文本数据的读取方法")

    class Sata(All_file): #子类继承抽象类,但是必须定义read和write方法

    def read(self):

    print("硬盘数据的读取方法")

    def write(self):

    print("硬盘数据的读取方法")

    class Process(All_file): #子类继承抽象类,但是必须定义read和write方法

    def read(self):

    print("进程数据的读取方法")

    def write(self):

    print("进程数据的读取方法")

    wenbenwenjian=Txt()

    yingpanwenjian=Sata()

    jinchengwenjian=Process()

    #这样大家都是被归一化了,也就是一切皆文件的思想

    wenbenwenjian.read()

    yingpanwenjian.write()

    jinchengwenjian.read()

    print(wenbenwenjian.all_type)

    print(yingpanwenjian.all_type)

    print(jinchengwenjian.all_type)

    # 抽象类 : 规范

    # 一般情况下 单继承 能实现的功能都是一样的,所以在父类中可以有一些简单的基础实现

    # 多继承的情况 由于功能比较复杂,所以不容易抽象出相同的功能的具体实现写在父类中

    # 抽象类还是接口类 : 面向对象的开发规范 所有的接口类和抽象类都不能实例化

    # python

    # python中没有接口类 :

    # python中自带多继承 所以我们直接用class来实现了接口类

    # python中支持抽象类 : 一般情况下 单继承 不能实例化

    # 且可以实现python代码

    展开全文
  • Python 对象模型

    2016-12-23 22:49:54
    是不是像其它编程语言一样(例如 Java),在 Python 中的一切都基类的实例?如果,那么 Python 中的基类什么?我听说过 Python 中的 object ,它那个基类吗?    Python 中这一块的内容相当复杂。Pyt

    1. Python中的旧式类与新式类

      你一定在其它地方见过这样的表述,“在 Python 中,一切皆对象”。
      
      那么,它意味着什么呢?是不是像其它编程语言一样(例如 Java),在 Python 中的一切都是基类的实例?如果是,那么 Python 中的基类是什么?我听说过 Python 中的 object 类,它是那个基类吗?
      
      Python 中这一块的内容相当复杂。Python 有旧式类和新式类两种模型。事实上,在早期 Python 版本中,Python 对于任何对象都没有显示的基类。但从 2.2 版本开始,引入了新式类,我们可以(或者必须)让每个对象都是 object 的子类。
      
      直到 Python 2.1 ,旧式类还一直是用户唯一可用的风格。旧式类与类型的概念无关。如果 x 是旧式类的实例,x.class 将应用 x 所属的类。但 type(x) 并不如此。我们来看一下下面的代码。
      这里写图片描述
      
      新样式类是从 Python 2.2 引入的。 它旨在为 Python 提供一个统一的对象模型。 在新式类中,引入了 object 类。 一切都继承自 object
      这里写图片描述
      
      新式类是通过继承自 object 类来定义的。 与旧式类不同,如果x是新样式类的实例,那么 x.classtype(x) 都指x所属的类。
      这里写图片描述
      
      为了与老版本兼容,Python 中的类仍然默认使用旧式类。 如果我们想使用新式类,我们需要定义类为 object 的子类。

    2. 旧式类与新式类的不同

      旧式类与新式类之间的显著不同在于类型系统。
      
      我们来看一下旧式类和新式类处理多重继承。 “多重继承”是指一个类可以继承自多个类。 如果A继承自B,A是B的子类(派生类),B是A的超类(基类或者父类)。

      多重继承允许一个类A可以有很多父类(我个人不喜欢多重继承,当一个类可以有很多父类的时候,它会变得相当奇怪。为了解决这个问题,其他编程语言支持另外的模型,像 Java 中的接口 或者是 Ruby 中的混入。就我个人而言,我非常喜欢Ruby的混入模型)。

      在 Python 对象模型中,每个类都有基类属性,它们按继承中的出现顺序存储所有的父类。
      这里写图片描述
      
      那么,多重继承有什么问题呢?
      
      多重继承的问题是超类的顺序。 为什么继承顺序很重要? 因为当子类的实例访问属性(变量或函数)时。 首先,它会在自己的空间来查找该属性,如果未找到该属性,它将继续查找类空间。 如果仍然找不到,搜索方法继续超类空间。 当一个类有许多超类时,超类的顺序就是搜索方法中的顺序。 在旧式类中,超类的顺序是深度优先,从左到右按照基类列表中的出现顺序。
      这里写图片描述

      旧式类方法的解析相当简单易懂,对吧? 但是,如果我们遵循这种规则,有时我们会在继承时犯错误。 例如,我们创建一个类G继承自A,D和E,而A是D和E的父类。它应该在这个上下文中抛出一个错误,以防止像这样的循环继承。
      
      新式类解决了这个问题。 新式类从 Python 2.3 引入了 MRO(方法解析顺序)。 MRO 的算法可以描述如下 

    def mro(cls):
        """
        Return ordering of superclass of cls
        This ordering was used when we want to access class instance atrribute
    
        `cls`: class type we want to resolve
    
        @raise `TypeError` if cannot resolution superclass order
        @return `list` of class
        """
        bases_cls = cls.__bases__
        mro_base_lists = [mro(base_cls) for base_cls in bases_cls]
        mro_list = [cls]
        while mro_base_lists:
            # find the good head
            # good head is head of a list which is not is tail of any list in mro_base_lists
            list_head = (x[0] for x in mro_base_lists)
            set_tails = set()
            for x in mro_base_lists:
                set_tails.update(x[1:])
    
            good_head = None
            for head in list_head:
                if head not in set_tails:
                    good_head = head
                    break
    
            # if cannot find good_head, raise TypeError
            if not good_head:
                raise TypeError
            else:
                # add to mro_list
                mro_list.append(good_head)
    
                # remove good_head in all list and add to mro_list
                for alist in mro_base_lists:
                    try:
                        alist.remove(good_head)
                    except Exception:
                        pass
                mro_base_lists = [x for x in mro_base_lists if x]
        return mro_list
    
    class A: pass
    class B(A): pass
    class C(A): pass
    class D(B, C): pass
    class E(C, B): pass
    class F(D, E): pass
    
    def test_mro():
        assert mro(A) == [A]
        print "Test1 passed"
    
        assert mro(B) == [B, A]
        print "Test2 passed"
    
        assert mro(C) == [C, A]
        print "Test 3 passed"
    
        assert mro(D) == [D, B, C, A]
        print "Test 4 passed"
    
        assert mro(E) == [E, C, B, A]
        print "Test 5 passed"
    
        try:
            mro(F)
        except Exception as e:
            assert isinstance(e, TypeError)
            print "Test 6 passed"
    
    test_mro()
    

      
      MRO算法的思想源于基类排序情况:如果B是C的子类,B总是在列表中的C之前。 这就是为什么我们收到一个 TypeErorr 如果我们定义类D(B,C)和E(C,B)之后定义F(D,E)。
      
      想更多的了解 MRO 是如何工作的,你应该参阅 The Python 2.3 Method Resolution Order
      
      新式类和旧式类的不同不仅体现在基类顺序方面。 我会在下一篇文章中介绍这个主题。
     
     原文链接: Python Object Model

    展开全文
  • Python支持多种类型的编程范式,...对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。 本文无法涵盖这些主题的所有详细信息。Pyt...

    Python支持多种类型的编程范式,例如过程式编程、函数式编程、面向对象编程,而且还可以融合多种类型的范式。

    现如今面向对象编程的使用非常广泛。面向对象编程的基本元素是对象,其包含的数据成员称为属性,函数(例程、过程)称为方法。

    对象是类的实例。换句话说,类主要定义对象的结构,然后我们以类为模板创建对象。类不但包含方法定义,而且还包含所有实例共享的数据。

    本文无法涵盖这些主题的所有详细信息。Python中的面向对象编程还包含其他很多方面。希望本文能够为你学习Python及实现面向对象提供一个良好的开端。

    创建Python类

    我们可以使用关键字class定义Python类,关键字后面紧跟类的名称、分号和类的实现:

    >>> class MyClass:
    ...     pass
    ...
    

    按照惯例,Python类的命名采用首字母大写(即PascalCase)。

    现在让我们创建这个新类的一个实例,名为MyClass:

    '''
    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
    互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    >>> a = MyClass()
    >>> a
    <__main__.MyClass object at 0x7f32ef3deb70>
    

    语句a = MyClass()创建了MyClass的一个实例,并将它的引用赋值给变量a。

    我们可以通过Python内置的函数type()或直接通过属性.__ class__来获取类型(即对象的类)。在拿到类(类型)之后,我们就可以利用属性.__ name__获取类的名字:

    >>> type(a)
    <class '__main__.MyClass'>
    >>> a.__class__
    <class '__main__.MyClass'>
    >>> a.__class__.__name__
    'MyClass'
    

    顺便提一句,Python类也是对象。它们是type的实例:

    >>> type(MyClass)
    <class 'type'>
    

    下面,我们来定义一个方法。

    Python中每个实例方法的第一个参数必须对应于该实例,即该对象本身。按照惯例,这个参数名为self。后面是其他参数(如果有需要的话)。在调用方法时,我们无需明确提供与参数self相对应的参数。
    通常,我们需要定义的一个最重要的方法是.init()。在类的实例创建后就会调用这个方法。该方法负责初始化类成员。我们定义的.init()如下:

    '''
    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
    互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    >>> class MyClass:
    ...     def __init__(self, arg_1, arg_2, arg_3):
    ...         print(f'an instance of {type(self).__name__} created')
    ...         print(f'arg_1: {arg_1}, arg_2: {arg_2}, arg_3: {arg_3}')
    ...
    

    下面,我们来创建一个MyClass实例,看看这个初始化方法的具体工作。我们的.init()方法需要三个参数(arg_1、arg_2和arg_3),记住我们不需要传递与self对应的第一个参数。所以,在实例化对象时,我们需要传递三个参数:

    >>> a = MyClass(2, 4, 8)
    an instance of MyClass created
    arg_1: 2, arg_2: 4, arg_3: 8
    

    上述声明产生的结果如下:

    • 创建一个MyClass类型的对象的实例。
    • 自动调用该实例的方法.__ init__()。
    • 我们传递给MyClass()方法的参数:(2,4和8)会被传递给.__ init__()。
    • __ init__()执行我们的请求,并输出结果。它利用type(self).__ name__获取类的名称。
      现在我们得到了一个类,它有一个方法.__ init__(),以及这个类的一个实例。

    数据属性

    下面我们来修改MyClass,增加一些数据属性。
    我们利用.__ init__()初始化和定义了实例,我们还可以在这个方法或其他实例方法中,通过给某个数据属性赋值的方式改变属性值:

    >>> class MyClass:
    ...     def __init__(self, arg_1, arg_2, arg_3):
    ...         self.x = arg_1
    ...         self._y = arg_2
    ...         self.__z = arg_3
    ...
    

    现在MyClass有三个数据属性:

    • .x可以获取arg_1的值
    • ._y可以获取arg_2的值
    • .__ z可以获取arg_3的值

    我们可以利用Python的解包机制,用更紧凑的形式编写这段代码:

    '''
    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
    互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    >>> class MyClass:
    ...     def __init__(self, arg_1, arg_2, arg_3):
    ...         self.x, self._y, self.__z = arg_1, arg_2, arg_3
    ...
    

    属性名称中的下划线(_)是为了表明这些属性是“私有”属性:

    开头没有下划线的属性(比如.x)通常可供对象外部的调用和修改。
    开头拥有一个下划线的属性(比如._y)通常也可以从对象外部调用和修改。然而,下划线是一种惯用的标志,即该类的创建者强烈建议不要使用该变量。应该仅通过类的功能成员(比如方法和属性)调用和修改该变量。

    开头拥有双下划线的属性(比如.__ z)将在名字修饰过程中被改名(在本例中它将被改名为._ MyClass __ z)。你也可以通过这个新名称从对象外部调用和修改它们。但是,我强烈反对这种做法。应该尽通过类的功能成员以其原始名称进行调用和修改。

    Python对象的数据属性通常存储在名为.__ dict__的字典中,它也是对象的属性之一。但是,你也可以将数据属性存储在其他地方。我们可以直接访问__dict__,或利用Python的内置函数vars()获取.__ dict__:

    '''
    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
    互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    >>> a = MyClass(2, 4, 8)
    >>> vars(a)
    {'x': 2, '_y': 4, '_MyClass__z': 8}
    >>> a.__dict__
    {'x': 2, '_y': 4, '_MyClass__z': 8}
    

    名字修饰过程把键’__z’变成了’_MyClass__z’。

    我们可以把.__ dict__当成普通的Python字典使用。
    获取和修改与数据属性关联的值的常规方法如下:

    >>> a.x
    2
    >>> a._y
    4
    >>> a.__z
    Traceback (most recent call last):
      File "<stdin>", line 1, in <module>
    AttributeError: 'MyClass' object has no attribute '__z'
    >>> a.x = 16
    >>> a.x
    16
    >>> vars(a)
    {'x': 16, '_y': 4, '_MyClass__z': 8}
    

    请注意,我们无法访问 __ z,因为__ dict__没有键’__z’。

    实例方法

    下面,我们来创建两个实例方法:
    ●.set_z():修改.__ z。
    ●.get_z():返回.__ z的值。
    请记住,每个实例方法的第一个参数(按照约定名为self)引用对象本身,但我们无需在调用方法时指定这个参数:

    '''
    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
    互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    >>> class MyClass:
    ...     def __init__(self, arg_1, arg_2, arg_3):
    ...         self.x, self._y, self.__z = arg_1, arg_2, arg_3
    ...     
    ...     def set_z(self, value):
    ...         self.__z = value
    ...     
    ...     def get_z(self):
    ...         return self.__z
    ...
    >>> b = MyClass(2, 4, 8)
    

    方法.get_z()和.set_z()提供了传统的检索和修改.__ z值的方法:

    >>> b.get_z()
    8
    >>> b.set_z(16)
    >>> vars(b)
    {'x': 2, '_y': 4, '_MyClass__z': 16}
    

    你也可以在.get_z()和.set_z()中添加其他功能,例如检查数据的有效性。这种方法实现了面向对象编程中的一个主要概念:封装。

    属性

    还有一种方法(一种更Python的方式)访问和修改数据属性是使用属性。属性封装了一系列方法:getter、setter和deleter,但其行为与普通的数据属性相同。
    下面的代码实现了属性.z,其中还包含.get_z()和.set_z()的功能:

    '''
    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
    互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    >>> class MyClass:
    ...     def __init__(self, arg_1, arg_2, arg_3):
    ...         self.x, self._y, self.__z = arg_1, arg_2, arg_3
    ...     
    ...     @property
    ...     def z(self):
    ...         return self.__z
    ...     
    ...     @z.setter
    ...     def z(self, value):
    ...         self.__z = value
    ...
    >>> b = MyClass(2, 4, 8)
    

    如下,我们利用相应的属性.z来访问和修改数据属性.__ z:

    >>> b.z
    8
    >>> b.z = 16
    >>> vars(b)
    {'x': 2, '_y': 4, '_MyClass__z': 16}
    

    这段代码比上述示例更精简优雅。

    类与静态方法

    除了实例方法和属性之外,类还可以拥有类方法和静态方法。
    下面让我们为MyClass添加三个方法:

    '''
    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
    互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    >>> class MyClass:
    ...     def __init__(self, arg_1, arg_2, arg_3):
    ...         self.x, self._y, self.__z = arg_1, arg_2, arg_3
    ...     
    ...     def f(self, arg):
    ...         print('instance method f called')
    ...         print(f'instance: {self}')
    ...         print(f'instance attributes:\n{vars(self)}')
    ...         print(f'class: {type(self)}')
    ...         print(f'arg: {arg}')
    ...     
    ...     @classmethod
    ...     def g(cls, arg):
    ...         print('class method g called')
    ...         print(f'cls: {cls}')
    ...         print(f'arg: {arg}')
    ...     
    ...     @staticmethod
    ...     def h(arg):
    ...         print('static method h called')
    ...         print(f'arg: {arg}')
    ...
    >>> c = MyClass(2, 4, 8)
    

    方法.f()是一个实例方法。实例方法的第一个参数是对象本身的引用。这些方法可以利用self访问对象,利用vars(self)或self.__dict__访问对象的数据属性,还可以利用type(self)或self.__class__访问对象对应的类,而且它们还可以拥有自己的参数。

    方法.g()的开头包含修饰器@classmethod,表明这是一个类方法。每个类方法的第一个参数都会指向类本身,按照约定该参数名为cls。与实例方法的情况一样,我们不需要明确提供与cls对应的参数。而类方法可以利用cls和自己的参数访问类本身。

    方法.h()的开头包含修饰器@staticmethod,表明这是一个静态方法。静态方法只能访问自己的参数。
    Python中常见的调用实例方法的方法如下:

    >>> c.f('my-argument')
    instance method f called
    instance: <__main__.MyClass object at 0x7f32ef3def98>
    instance attributes:
    {'x': 2, '_y': 4, '_MyClass__z': 8}
    class: <class '__main__.MyClass'>
    arg: my-argument
    

    通常,我们应该直接通过类(而不是实例)调用类方法和静态方法:

    '''
    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
    互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    >>> MyClass.g('my-argument')
    class method g called
    cls: <class '__main__.MyClass'>
    arg: my-argument
    >>> MyClass.h('my-argument')
    static method h called
    arg: my-argument
    

    请记住,我们不需要传递类方法的第一个参数:与cls相对应的参数。

    但是,我们可以像下面这样调用类方法和静态方法:

    >>> c.g('my-argument')
    class method g called
    cls: <class '__main__.MyClass'>
    arg: my-argument
    >>> c.h('my-argument')
    static method h called
    arg: my-argument
    

    当我们调用c.g或c.h,但实例成员没有这样的名称时,Python会搜索类和静态成员。

    继承

    继承是面向对象编程的另一个重要特性。在这个概念中,类(称为子类或派生类)会继承其他类(称为超类或基类)的数据和函数成员。
    在Python中,所有类都会默认继承Python自带的类对象。但是,我们可以根据需要定义合适的类继承层次结构。
    例如,我们可以创建一个名为MyOtherClass的新类,该类继承了MyClass:

    '''
    遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 寻找有志同道合的小伙伴,
    互帮互助,群里还有不错的视频学习教程和PDF电子书!
    '''
    >>> class MyOtherClass(MyClass):
    ...     def __init__(self, u, v, w, x, y, z):
    ...         super().__init__(x, y, z)
    ...         self.__u, self.__v, self.__w = u, v, w
    ...     
    ...     def f_(self, arg):
    ...         print('instance method f_ called')
    ...         print(f'instance: {self}')
    ...         print(f'instance attributes:\n{vars(self)}')
    ...         print(f'class: {type(self)}')
    ...         print(f'arg: {arg}')
    ...
    >>> d = MyOtherClass(1, 2, 4, 8, 16, 32)
    

    如上,MyOtherClass拥有MyClass的成员:.x、._ y、.__ z以及.f()。你可以通过语句super().__ init__(x, y, z)初始化基类的数据成员x、._ y和.__ z,该语句会调用基类的.__ init__()方法。

    除此之外,MyOtherClass还有自己的成员:.__u、.__v、.__w和.f _()。
    下面,我们通过vars()获取数据成员:

    >>> vars(d)
    {'x': 8,
     '_y': 16,
     '_MyClass__z': 32,
     '_MyOtherClass__u': 1,
     '_MyOtherClass__v': 2,
     '_MyOtherClass__w': 4}
    

    我们可以调用基类和派生类中的所有方法:

    >>> d.f('some-argument')
    instance method f called
    instance: <__main__.MyOtherClass object at 0x7f32ef3e7048>
    instance attributes:
    {'x': 8,
     '_y': 16,
     '_MyClass__z': 32,
     '_MyOtherClass__u': 1,
     '_MyOtherClass__v': 2,
     '_MyOtherClass__w': 4}
    class: <class '__main__.MyOtherClass'>
    arg: some-argument
    >>> d.f_('some-argument')
    instance method f_ called
    instance: <__main__.MyOtherClass object at 0x7f32ef3e7048>
    instance attributes:
    {'x': 8,
     '_y': 16,
     '_MyClass__z': 32,
     '_MyOtherClass__u': 1,
     '_MyOtherClass__v': 2,
     '_MyOtherClass__w': 4}
    class: <class '__main__.MyOtherClass'>
    arg: some-argument
    

    但是,如果派生类包含的某个成员与基类同名,则优先使用派生类的成员。

    总结

    面向对象编程是Python支持的编程范式之一。面向对象蕴含的抽象以及表征的现实世界行为在某些时候会非常有帮助性。然而,有时也可能会违反直觉,并为开发过程带来不必要的麻烦。
    在本文中,我们介绍了如何利用Python编写基本的面向对象程序。Python中还有很多类和面向对象的功能,例如:

    • 方法:.__ repr__()和.__ str__()
    • 方法:.__ new__()
    • 操作符
    • 方法:.__ getattribute__()、.__ getattr__()、.__ setattr__()和.__ delattr__()
    • 生成器
    • 可调用性
    • 创建序列
    • 描述器
    • 上下文管理
    • 抽象类和成员
    • 多重继承
    • 使用super()
    • 拷贝
    • 序列化
    • slot
    • 类修饰器
    • 数据类
      等等……

    现如今面向对象是非常流行的编程方式。如果你立志做一名Python开发人员,那么就应该学习面向对象编程。但请不要忘记,Python还支持其他编程范式,例如过程式编程、函数式编程等,在某些情况下也许选用这些范例更为合适。

    尽情享受编程的快乐!

    原文:https://www.blog.duomly.com/object-oriented-programming-in-python/

    展开全文
  • 日常中,我们天天都在用 Python 中的类,貌似类的相关内容已经没有什么新奇的了,可是,你真的 创建 过类吗? 通常,我们所做的不过用 class 来 声明 一个类,而后利用它来 创建实例对象。 那么,具体的类创建 又...
  • 读到这里,一定会有很多小伙伴会说,我PyCharm(也可能VSCode或者其他什么)也会告诉我,当前的对象有什么属性和方法,还是自动显示,不需要我动手。没错,IDE的确为我们提供了很多便利,但是,你有没有想过...
  • python

    2019-09-09 20:25:51
    你创建类就是为了创建类的实例对象,不是吗?但是我们已经学习到了Python中的类也是对象。 元类就是用来创建这些类(对象)的,元类就是类的类,你可以这样理解为: MyClass = MetaClass() # 使用元类创建出一个对象...
  • 1.之前我理解类为了节省时间演化来的,因此里面的类的静态属性应该和模块中的全局变量作用范围类似,那类中的静态属性应该在整个类中都能访问。但实际为代码段所示。 2. ``` 2.1 全局变量能被内部定义函数所...
  • Python

    2019-10-12 09:00:20
    你创建类就是为了创建类的实例对象,不是吗?但是我们已经学习到了Python中的类也是对象。好吧,元类就是用来创建这些类(对象)的,元类就是类的类。 我要一大群的类都具有一种特点,我怎么给他们加上呢?模板嘛,...
  • python类共享变量操作

    2021-01-19 23:43:03
    python类对象A,先实例化一个A对象的实例b,接着给A对象添加一个共享变量xxx,再实例化一个c,请问b 和c都有变量xxx吗 解答: python类共享变量,不需要实例化就可以调用的, 比如A有一个XXX的共享变量, ...
  • 你觉得网络上像msn,qq之类的工具在多台机器之间互相传输数据神秘吗?你也想玩一下在两台机器之间传数据吗?今天让python告诉我们基本原理吧,当然只是做简单的了解,实际情况复杂的多。  我们今天用python实现一...
  • python类共享变量详解

    千次阅读 2018-08-27 11:40:43
    python类对象A,先实例化一个A对象的实例b,接着给A对象添加一个共享变量xxx,再实例化一个c,请问b 和c都有变量xxx吗   解答: python类共享变量,不需要实例化就可以调用的, 比如A有一个XXX的共享...
  • 这个问题已经有了一个答案: Python中的元类是什么?14答案 我偶然发现这条巨蟒文献资料在super关键词: 如果省略了第二个参数,则返回的超级对象将被解除绑定。...文档在谈论对象的实例吗? 谢谢。 Python
  • 通过__builtins__可以查看python内置一些对象、函数、实例。 不难发现,__builtins__返回值竟然达到了154个之多。内置函数只占一半,即便如此,就算聪明绝顶人也怕一时半会消化不了吧。 学英语同样学...
  • 1)字段我们首先要明白,我们之前讲大部分情况对象或者说是实例进行操作。但是,事实上有各种操作。我们之前一直所说”属性“其实字段。你可能要骂我了,你之前不是说属性吗?这个字段,那...
  • 是类的实例化,既然一切皆对象,那么对象的模版,类也是对象,那不就成了对象创建了对象了吗?下面看这样一个例子 a = 1 print(type(a)) print(type(int)) print(type(type)) 运行结果 <class 'int'> <...
  • 个人感受: 比如pandas.Dataframe()库的方法?df.loc()是对象方法?还有dataframe这种新的数据类型?这如何实现的呢? 与类的属性和类方法、实例方法相同吗?
  • python__metaclass__

    2015-08-08 21:09:00
    你创建类就是为了创建类的实例对象, 不是吗? 但是我们已经学习了python中的类也是对象. 元类就是用来创建这些类对象的, 元类就是类的类, 你可以这样理解: MyClass = MetaClass() MyObject = MyClass() 你...
  • 关于Python的问题

    2020-04-12 15:58:53
    一个类的进行了实例化为了a后,b对a进行了拷贝,那在b上做的操作会影响到a吗? 浅拷贝,如果容器里面的项引用,拷贝的就是引用,此引用指向相同的对象。深拷贝,如果容器里面的项引用,拷贝的引用所指向的...
  • 在上一篇博文里,传入参数时,实例对象后且在调用方法时才传入参数,感觉是不是有点繁琐对吧?可以在实例时候就传入参数吗?可以,这就是本篇博文要讲到构造器——__init__(两边双下划线)__init__...
  • 在上一篇博文里,传入参数时,实例对象后且在调用方法时才传入参数,感觉是不是有点繁琐对吧?可以在实例时候就传入参数吗?可以,这就是本篇博文要讲到构造器——__init__(两边双下划线) __init__...
  • Python 蓝图

    2018-11-03 18:07:47
    由于上面的例子中只有两个组件(模块)admin,user,我们可以创建名为admin.py和user.py的两个文件,分别在里面创建两个蓝图的实例对象admin,user. 直接上代码: #admin.py #admin.py from flask import Blueprint,render_...
  • 赋值,其实就是对象的引用,对新对象的如何修改都会影响到...浅拷贝与深拷贝差异只与复合对象对象中包含其他对象,比如列表或类实例)相关。 浅拷贝构造新复合对象,然后向其插入对原始对象对象(即子对...
  • python菜鸟记录

    2021-01-12 21:08:52
    self代表类的实例,而非类 类的方法与普通的函数只有一个特别的区别——它们必须有一个额外的第一个参数名称, 按照惯例它的名称 self。 self只有在类的方法中才会有,独立的函数或方法不必带有self的。 self...
  • 被忽略的对象

    2018-06-13 15:42:00
    然而在学习python的过程中,我们还是会把一些经常出现在我们眼前的对象给忽略,而通过我们自己实例出来的类的对象倒是不会搞错(这灯下黑吗?还是越容易得手的越不珍惜?)。而python的一些语法定义中,“对象”一...
  • 2017-10-29 22:16:00
    你创建类就是为了创建类的实例对象,不是吗?但是我们已经学习到了Python中的类也是对象。好吧,元类就是用来创建这些类(对象)的,元类就是类的类,你可以这样理解 为: 这因为函数type实际上一个元类。type...
  • 0. 自 Python2.2 以后,对和类型进行了统一,做法就是将 int()、float()、str()、list()、tuple() 这些 BIF 转换为工厂函数。请问所谓工厂函数,其实什么原理? 1. 当实例对象进行加法操作时,会自动调用什么...
  • metaclass(元)

    2017-07-19 16:18:00
    你创建类就是为了创建类的实例对象,不是吗?但是我们已经学习到了Python中的类也是对象。好吧,元类就是用来创建这些类(对象)的,元类就是类的类,你可以这样理解 为: 1 2 MyClass =...

空空如也

空空如也

1 2 3
收藏数 52
精华内容 20
关键字:

python对象是类的实例吗

python 订阅