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就是对类的数据属性进行操作,和上面的例子有本质上的区别。

  • 相关阅读:
    POJ 1401 Factorial
    POJ 2407 Relatives(欧拉函数)
    POJ 1730 Perfect Pth Powers(唯一分解定理)
    POJ 2262 Goldbach's Conjecture(Eratosthenes筛法)
    POJ 2551 Ones
    POJ 1163 The Triangle
    POJ 3356 AGTC
    POJ 2192 Zipper
    POJ 1080 Human Gene Functions
    POJ 1159 Palindrome(最长公共子序列)
  • 原文地址:https://www.cnblogs.com/maoxinjueluo/p/12612785.html
Copyright © 2011-2022 走看看