百科问答小站 logo
百科问答小站 font logo



如何理解python的类与对象? 第1页

  

user avatar   opendilab 网友的相关建议: 
      

不多说,一图流


咳咳,正经的解释一下,首先这是一个很经典的问题。我们此处假设题主对面向对象以及建模不够了解,先说一说这个类与对象的基本概念(如果这部分已经了解的话可以直接跳到本回答的“当类与对象遇到 Python”部分)。

何谓类与对象

首先一个最典型的例子,设想一个国家有这么几个人:

  • 张三,性别男,爱好女,29 岁,身高 173

  • 李四,性别男,爱好不限,32 岁,身高 182

  • 王五,性别女,爱好男,40 岁,身高 165

通过这么一看,这三位看起来都有个共同的特点——都是人。没错,先别吐槽,我知道这是一句废话,但是咱们接下来用逻辑视角来尝试推演这个例子:

  • 首先,在此之前有了一个“人”的概念

  • 其次,一般意义是的“人”,应该有个“名字”,也应该有“性别”、“爱♂好♀”,以及“岁数”和“身高”,用于对其进行描述

  • 然后,基于这些特性,有了对“张三”、“李四”、“王五”三个个体的描述

这实际上就是一种面向对象的思维方式。让我们回到这个问题上来——“何谓类与对象”?结合上面的例子应该是这样的:

  • “人”这一概念是一个类(Class)
    • 其中“名字”、“性别”、“爱好”、“岁数”和“身高”是这个类的字段(Field)

  • “张三”、“李四”、“王五”这些个体是对象(Object),或者更准确的说,是基于“人”类的“人”对象,也可以称之为“人”实例(Instance)
    • 对于这三个对象而言,其具体的字段信息(例如“张三”、“29 岁”、“165”等具体值)即为对象的属性(Property)

这就是一个对类与对象最为简单的诠释。

然后我们再来看看对“类”的正经定义(来自英文维基: Class (knowledge representation)

In knowledge representation, a class is a collection of individuals or objects. A class can be defined either by extension (specifying members), or by intension (specifying conditions), using what is called in some ontology languages like OWL. According to the Type–token distinction, the ontology is divided into individuals, who are real worlds objects, or events, and types, or classes, who are sets of real world objects. Class expressions or definitions gives the properties that the individuals must fulfill to be members of the class. Individuals that fulfill the property are called Instances.

其中比较重要的内容包含:

  • 类是个体或对象的集合
  • 类定义给出了个人必须满足才能成为类成员的属性,满足该属性的个体称为实例

简单来说,类定义了一类个体和对象的概念,而对象则是这一概念下符合其模式的个体

说到这里需要明确,类和对象本质上是一个无处不在的抽象概念,和包括 Python 在内的任何一门具体的高级语言或者建模工具无必然联系。换言之,只要有定义,有概念,就足以形成类(Class),而当一个个体满足类所描述的模式时,这一个体即为对象(Object)

而当提到面向对象的概念,大家最熟悉的可能还是基于代码的形态,例如在 Java 中(此处部分写法并不标准,仅作示意用)

       // definition of class Person public class Person {     public final String name;     public final String gender;     public final String preference;     public final int age;     public final int height;          public Person(String name, String gender, String preference, int age, int height) {         this.name = name;         this.gender = gender;         this.preference = preference;         this.age = age;         this.height = height;     } }  // instantiation zhangSan = Person("Zhang San", "Male", "Female", 29, 173) liSi = Person("Li Si", "Male", "Anything", 32, 182) wangWu = Person("Wang Wu", "Female", "Male", 40, 165)     

以及在 Python 中

       # definition of class Person class Person:     def __init__(self, name, gender, preference, age, height):         self.name = name         self.gender = gender         self.preference = preference         self.age = age         self.height = height  # instantiation zhang_san = Person("Zhang San", "Male", "Female", 29, 173) li_si = Person("Li Si", "Male", "Anything", 32, 182) wang_wu = Person("Wang Wu", "Female", "Male", 40, 165)     

都是对上述例子的一种语言表示,也是我们所常说的类与对象。而在 Java 与 Python 中更多的例子与讲解可以参考这里:


当类与对象遇到 Python

先说结论:

  • Python中一切皆对象,类也是一种对象
  • Python中一切对象本质都是一种和 dict 类型类似的映射结构

比如通过这样的方式,就能知道一个对象里面都有啥,其中dir函数可以展示一个类内部所包含的全部字段,__dict__属性可以近似地视为包含主要属性,如下代码所示

       class T:     def __init__(self, x, y, z):         self.x = x         self._y = y         self.__z = z      def one_method(self, t):         return self.x + self._y + self.__z + t    t = T(1, 2, 3) print(dir(t)) print(set(dir(t)) - set(dir(object()))) print(t.__dict__)  # ['_T__z', '__class__', '__delattr__', '__dict__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__', '_y', 'one_method', 'x'] # {'__weakref__', '__module__', '_y', '__dict__', 'x', '_T__z', 'one_method'} # {'x': 1, '_y': 2, '_T__z': 3}     

没错,实际上在Python中,无论是方法还是属性(包括私有属性在内),本质上是差不多的,都是挂载在对象上的一个键值对。而当你去尝试调用一个对象的方法时,实际上也是在向该对象获取方法可执行对象(可以近似地理解为一个函数),然后再执行。

在上面的示例代码中,公有(public)和保护(protected)属性x_y直接存在于对象中,私有属性__z实质上以_T__z的形式存在于对象中,连包括__init__one_method在内的各个方法也均被包含在dir函数的结果之内,此等现象足以大致说明Python对象的本质。

关于这部分其实学问还是很深的,OpenIDLab的研发人员也对这部分进行过一些微小的研究,欢迎进一步阅读。





  

相关话题

  学计算机的男生发这个给我看是什么意思? 
  如何生成多个互不重叠的不同半径圆? 
  数据分析为什么常用Jupyter而不是直接使用Python脚本或Excel? 
  如何评价潘石屹说python是最接近日常语言的编程语言? 
  python到底学什么? 
  为什么 Python 的 GIL 问题一直让人诟病,Python 社区却不解决? 
  Python中一个字符串的所有字母用它的后继字母代替(比如,a用b代替,b用c代替),怎么搞? 
  计算机大一新生,压力大,天天都在学习,我该怎么办? 
  会多门编程语言的你,最推荐哪3-5门语言? 
  Python 中有什么不容易让人察觉的有趣的事实? 

前一个讨论
如何快速确定有机合成产物?
下一个讨论
在图像处理中,散度 div 具体的作用是什么?





© 2024-09-19 - tinynew.org. All Rights Reserved.
© 2024-09-19 - tinynew.org. 保留所有权利