zoukankan      html  css  js  c++  java
  • Python之面向对象思想


    本节掌握两个知识点:
              一、什么叫面向对象
              二、类的属性和对象的属性

    首先在了解面向对象之前,我们先来看一个例子:假设我们是一个上帝,现在我们要来生产一条狗,我们假设狗有两个动作:叫还有看门,狗有三个属性:名字、性别、品种,下面我们就来模拟这一条狗,由于狗的动作是固定的,所以我们可以把动作写成方法。
     1 og1 = {
     2     'name':'旺财',
     3     'gender':'',
     4     'type':'哈士奇'
     5 }
     6 dog2 = {
     7     'name':'小狗',
     8     'gender':'',
     9     'type':'博美'
    10 }
    11 def jiao(dog):
    12     print('一条%s正在叫'%dog['name'])
    13 def kanmen(dog):
    14     print('一条%s正在看门'%dog['type'])
    15 jiao(dog1)
    16 kanmen(dog2)
    17 ##   一条旺财正在叫
    18 ##   一条博美正在看门
    我们很容易就发现问题了
    1 people1 = {
    2     'name':'小明',
    3     'gender':'',
    4     'type':''
    5 }
    6 kanmen(people1)
    7 #  一条人正在看门
    人怎么能调用狗的动作的,显然是不可以的,所以我们需要把狗的属性和动作捆绑在一起,只有具有狗的属性才能调用狗的动作
     1 def dog(name,gender,type):
     2     def jiao(dog):
     3         print('一条%s正在叫' % dog['name'])
     4 
     5     def kanmen(dog):
     6         print('一条%s正在看门' % dog['type'])
     7 
     8     dog1 = {
     9         'name': name,
    10         'gender': gender,
    11         'type': type,
    12         'jiao':jiao,
    13         'kanmen':kanmen
    14     }
    15     return dog1
    16 
    17 d1 = dog('旺财','','哈士奇')
    18 d2 = dog('小狗','','博美')
    19 print(d1)
    20 print(d2)
    21 d1['jiao'](d1)
    狗的动作和属性
    下面我们还可以优化一下
     1 def dog(name,gender,type):
     2     def init(name,gender,type):     ##  定义了狗的属性和动作,实际上就是初始化一只狗
     3         dog1 = {
     4                 'name': name,
     5                 'gender': gender,
     6                 'type': type,
     7                 'jiao':jiao,
     8                 'kanmen':kanmen
     9             }
    10         return dog1
    11     
    12     def jiao(dog):      ##  狗的动作
    13         print('一条%s正在叫' % dog['name'])
    14 
    15     def kanmen(dog):    ##  狗的动作
    16         print('一条%s正在看门' % dog['type'])
    17 
    18     return init(name,gender,type)
    19 d1 = dog('旺财','','哈士奇')
    20 d2 = dog('小狗','','博美')
    21 print(d1)
    22 print(d2)
    优化
    这样看起来代码就整洁多了,其中init()就是初始化一只狗,事实上上面就是一个面向对象设计了。我们来观察上面的例子,上面的dog()函数定义了动作与特征,也就是定义了狗这一个种类,而d1就是生成了实实在在的一个狗,也就是对象,所以面向对象包含了两大部分:类和对象。其中类就是一个种类,包含动作和属性。对象就是实例出来的一个具体的例子,只要符合这两点那就是一个面向对象设计。

    上面就是一个面向对象设计的例子了,下面我们来用面向对象编程来实现下面的例子:
     1 class Dog:
     2     def __init__(self,name,gender,type):        ##  这个就是上面的init() 函数,初始化函数,类一运行就会执行这个函数
     3         self.name = name
     4         self.gender = gender
     5         self.type = type
     6 
     7     def jiao(self):     ##  这里的self实际上就是对象本身
     8         print('一条%s正在叫'%self.name)
     9 
    10     def kanmen(self):
    11         print('一条%s正在看门'%self.type)
    12 
    13 d1 = Dog('旺财','','哈士奇')
    14 d2 = Dog('小狗','','博美')
    15 d1.jiao()
    16 d2.kanmen()
    17 #一条旺财正在叫
    18 # 一条博美正在看门
    面向对象编程

    下面我们来总结一下:

    1、面向对象分为两种:面向对象设计和面向对象编程,只要包含一类事物的总和(类 )以及这一类产生了实例,那就是一个面向对象。所以并不是包含class(类)才叫做面向对象。

    2、面向对象两个概念:类(class)和对象(object)。其中类就是一类事物的特征和动作的总和(例如人这一个种类),是一个抽象的概念。

      而对象就是由这一个类实例化出来的一个具体的例子,就好比是一个个的人。

    3、什么叫实例化:由类产生对象这一个过程就叫实例化,结果是一个对象或者叫一个实例。

    • 类的相关知识:

    类有两个属性:数据属性和函数属性

    1、下面我们来看一下类的数据属性和函数属性

     1 class Chinese:
     2     color = 'yellow'        ##  数据属性
     3     def quality():      ##  函数属性
     4         print('中国人有着勤劳勇敢的品德')
     5 
     6     def sell(self):     ##  函数属性
     7         print('中国人爱经商')
     8 
     9 ##  下面我们来打印Chinese这一类的数据属性和函数属性(方法属性)
    10 
    11 print(Chinese.color)        ##  yellow
    12 print(Chinese.quality)      ##  <function Chinese.quality at 0x000000000262E2F0>
    13 print(Chinese.sell)         ##  <function Chinese.sell at 0x000000000262E378>
    14 
    15 ##  我们来运行类的函数
    16 Chinese.quality()       ##  中国人有着勤劳勇敢的品德
    17 Chinese.sell(123)       ##  中国人有着勤劳勇敢的品德

    类有一个方法:__dict__,调用这个方法可以打印出类的所有属性,返回的是一个字典的形式,下面我们把类的属性打印出来

    print(Chinese.__dict__)     ##  {'__module__': '__main__', 'color': 'yellow', 'quality': <function Chinese.quality at 0x000000000216E2F0>, 'sell': <function Chinese.sell at 0x000000000216E378>, '__dict__': <attribute '__dict__' of 'Chinese' objects>, '__weakref__': <attribute '__weakref__' of 'Chinese' objects>, '__doc__': None}
    
    ##  我们把这个属性字典里的数据属性以及函数属性打印出来
    print(Chinese.__dict__['color'])        ##  yellow
    print(Chinese.__dict__['quality'])      ##  <function Chinese.quality at 0x000000000283E2F0>
    print(Chinese.__dict__['sell'])         ##  <function Chinese.sell at 0x000000000283E378>
    
    ##  我们把这个属性字典里的函数打印出来
    Chinese.__dict__['quality']()       ##  中国人有着勤劳勇敢的品德
    Chinese.__dict__['sell'](123)       ##  中国人爱经商

    实际上上面打印的 Chinese.color 这个数据属性就是从  __dict__  这里面的属性字典里面取出来的。

    2、知道了类的字典属性之后,我们可以对类的数据属性和函数属性进行增删改查:

     1 class Chinese:
     2     color = 'yellow'
     3     def __init__(self,name,age,gender):     ##  这里self 这个参数就是对象本身,实例化对象第一步就是运行 __init__() 这个函数
     4         self.name = name
     5         self.age = age
     6         self.gender = gender
     7 
     8     def quality():
     9         print('中国人有着勤劳勇敢的品德')
    10 
    11     def sell(self):
    12         print('中国人爱经商')
    13 
    14 p1 = Chinese('alex',18,'')
    15 ##  数据属性 增
    16 Chinese.Country = '中国'
    17 print(Chinese.__dict__['Country'])      ##  中国
    18 
    19 ##  删
    20 del Chinese.Country
    21 
    22 ##  改
    23 Chinese.color = '白色'
    24 print(Chinese.__dict__['color'])    ##  白色
    25 
    26 ##  函数属性 增
    27 def sport(self):
    28     print("中国人%s喜欢打乒乓球"%self.name)
    29 Chinese.sport = sport
    30 p1.sport()      ##  中国人alex喜欢打乒乓球
    31 
    32 ##  改 (其实就是重新写一个函数,去覆盖原来的函数)
    33 def sell(self):
    34     print('中国人%s爱占小便宜'%self.name)
    35 Chinese.sell = sell
    36 p1.sell()       ##  中国人alex爱占小便宜
    类属性 增删改查
    • 对象的相关知识

    1、我们首先来看一下对象有什么属性

     1 class Chinese:
     2     color = 'yellow'
     3     def __init__(self,name,age,gender):     ##  这里self 这个参数就是对象本身,实例化对象第一步就是运行 __init__() 这个函数
     4         self.name = name
     5         self.age = age
     6         self.gender = gender
     7 
     8     def quality():     
     9         print('中国人有着勤劳勇敢的品德')
    10 
    11     def sell(self):
    12         print('中国人爱经商')
    13 
    14 p1 = Chinese('alex',18,'man')
    15 print(p1.__dict__)      ##  {'name': 'alex', 'age': 18, 'gender': 'man'}

    可以看出来, p1 这个对象只有数据属性,那我们看一下能不能调用类的函数属性呢?

    1 print(p1.color)     ##  yellow  这里想一下:为什么明明p1 的字典属性里没有color这个数据属性,为什么这里能打印出来呢?
    2 p1.sell()       ##  中国人爱经商
    3 p1.quality()
    4 ## 报错: Traceback (most recent call last):
    5 #   File "F:/PycharmProjects/复习/面向对象/面向对象思想.py", line 152, in <module>
    6 #     p1.quality()
    7 # TypeError: quality() takes 0 positional arguments but 1 was given

    这里提出两个问题:

    (1)、为什么 p1 能够调用字典属性里面没有的数据属性和函数属性呢?

    (2)、为什么 p1 调用 quality()函数会报错呢?

    实际上这个就是作用域的原因,首先 p1 会在自己的字典属性里面找,如果找不到就会去类的字典属性里去找,我们可以看到类的字典属性里是有上面的数据属性和函数属性的,如果还找不到就会报错了。

    至于第二个问题,是因为对象在调用方法属性时,底层会自动把对象作为一个参数传入函数中,由于quality()里并没有接收这个参数,所以就报错了。

    2、同样,我们对实例(对象)属性进行增删改查

     1 class Chinese:
     2     color = 'yellow'
     3     def __init__(self,name,age,gender):
     4         self.name = name
     5         self.age = age
     6         self.gender = gender
     7 
     8     def quality():
     9         print('中国人有着勤劳勇敢的品德')
    10 
    11     def sell(self):
    12         print('中国人爱经商')
    13 
    14 p1 = Chinese('alex',18,'')
    15 print(p1.__dict__)      ##  {'name': 'alex', 'age': 18, 'gender': '男'}
    16 ##  改
    17 p1.name = '武则天'
    18 print(p1.__dict__)      ##  {'name': '武则天', 'age': 18, 'gender': '男'}
    19 ##  增
    20 p1.money = 1000000
    21 print(p1.__dict__)      ##  {'name': '武则天', 'age': 18, 'gender': '男', 'money': 1000000}
    22 ##  删
    23 del p1.money
    24 print(p1.__dict__)      ##  {'name': '武则天', 'age': 18, 'gender': '男'}
    对象的数据属性 增删改查

    补充:下面我们对类和对象的属性进行操作

    观察一下:

     1 class Chinese:
     2     color = 'yellow'
     3     def __init__(self,name,age,gender):
     4         self.name = name
     5         self.age = age
     6         self.gender = gender
     7 
     8     def quality():
     9         print('中国人有着勤劳勇敢的品德')
    10 
    11     def sell(self):
    12         print('中国人爱经商')
    13 
    14 p1 = Chinese('alex',18,'')
    15 p1.color = '白色的'
    16 print(Chinese.color)    ##  yellow

    想一下: 为什么我们通过 对象 修改了color这个类的数据属性时,类的数据属性并没有修改呢?

    我们打印一下对象的数据属性

    print(p1.__dict__)  ##  {'name': 'alex', 'age': 18, 'gender': '男', 'color': '白色的'}

    可以看出,实际上我们是在给对象属性增加了color这个元素,和类的color这个数据属性没有任何关系,只不过名字一样而已。

    那么下面继续看另一个操作:

     1 class Chinese:
     2     color = 'yellow'
     3     l = ['a','b']
     4     def __init__(self,name,age,gender):
     5         self.name = name
     6         self.age = age
     7         self.gender = gender
     8 
     9     def quality():
    10         print('中国人有着勤劳勇敢的品德')
    11 
    12     def sell(self):
    13         print('中国人爱经商')
    14 
    15 p1 = Chinese('alex',18,'')
    16 p1.l.append('c')
    17 print(Chinese.l)        ##  ['a', 'b', 'c']

    为什么这里类的属性被修改了呢?

    同样,我们打印一下对象的数据属性:

    print(p1.__dict__)      ##  {'name': 'alex', 'age': 18, 'gender': '男'}

    我们这里可以看出来,对象的数据属性并没有任何变化。事实上,这里append就是对类的数据属性进行操作,和上面的例子有本质上的区别。

  • 相关阅读:
    升级Nginx1.14.1以上版本
    MaxScale中间件部署数据库读写分离
    php文件锁解决少量并发问题
    使用mysql悲观锁解决并发问题
    配置和查看composer镜像
    PHP常用的 五种设计模式及应用场景
    全球免费公共 DNS 解析服务器 IP 地址列表推荐 (解决无法上网/加速/防劫持)
    九种跨域方式实现原理
    Hadoop中RPC协议小例子报错java.lang.reflect.UndeclaredThrowableException解决方法
    DataNode启动不成功——java.net.BindException: Port in use: localhost:0 Caused by: java.net.BindException: Cannot assign requested address解决办法
  • 原文地址:https://www.cnblogs.com/maoxinjueluo/p/12612785.html
Copyright © 2011-2022 走看看