七、面向对象编程(OOP)

面向对象编程:一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

1、类(class)

  • class:自定义的对象数据类型。基于类创建多个对象,每个对象具备类的通用行为,首字母大写(面向对象的设计思想是抽象出Class,根据Class创建Instance【实例】) 
  • __init__方法:第一个参数self表示创建的实例本身,在内部把各种属性绑定到self,因为self指向创建的实例本身。可把一些必要的属性先填进去,如:姓名、年龄等
 1 #创建一个类,假设为人
 2 class Person(object):
 3     #使用__init__方法初始化创建的实例属性
 4     def __init__(self,name,age,gender):
 5         self.name = name
 6         self.age = age
 7         self.gender = gender
 8     #定义创建的实例所拥有的技能
 9     def eat(self):
10         print('%s,You have the skills to eat' %self.name)
11     def motion(self):
12         print('%s,%s,is a %s'%(self.name,self.age,self.gender))
13 
14 #创建实例
15 j = Person('jack',18,'boy')
16 l = Person('lisa',18,'girl')
17 #使用技能
18 j.eat()
19 l.motion()
20 
21 输出:
22 jack,You have the skills to eat
23 lisa,18,is a girl

 

  • 数据封装:类本身所拥有的数据,在内部使用函数封装起来,称为类的方法。(如下文的print_name与get_name两个函数)

 

  • 访问限制:在方法前用双下划线:__xx 表示默认数据不被外部重新修改
     1 class Person(object):
     2     def __init__(self,name,age):
     3         self.__name = name
     4         self.__age = age
     5     def print_name(self):
     6         print('%s %s'%(self.__name,self.__age))
     7     #使用新函数为外部需要获取私有参数,外部无法直接使用self.name调用数据
     8     def get_name(self):
     9         return self.__name
    10 jack = Person('jack',19)
    11 print(jack.print_name())
    12 print(jack.get_name())
    13 
    14 输出:
    15 jack 19
    16 None
    17 jack
  • 继承:可以把父类的所有功能都直接拿过来,这样就不必重零做起,子类只需要新增自己特有的方法,也可以把父类不适合的方法覆盖重写。
    1 #Dog类继承Animal类,可使用其内部方法
    2 class Animal(object):
    3     def run(self):
    4         print('Animal is running')
    5 class Dog(Animal):
    6     pass
  • 测试对象属性:
    • hasattr(Person,'x'):判断Person对象是否有‘x’属性;
    • setattr(Person,'y',18):设置一个属性‘y’以及对应的值;
    • getattr(Person,'y',404):获取属性‘y’的值,如属性不存在时可设置返回值,不然会得到AttributeError的错误。
  • 类属性:直接在class中定义的属性,归类所有。所有实例共享一个属性;
  • 实例属性:属于各个实例所创建的属性,互不干扰(实例属性和类属性不使用相同的名字,相同时实例属性会屏蔽类属性)。
     1 class Animal(object):
     2     class_name = 'dog'    #类属性
     3     def __init__(self,name):
     4         self.name = name
     5 c = Animal('cat')   #实例属性
     6 print(c.name)
     7 print(c.class_name)
     8 
     9 输出:
    10 cat
    11 dog
  • super():是用于调用父类(超类)的一个方法
     1 class People(object):
     2     def print(self):
     3         print('父类方法')
     4 class Man(People):
     5     def print(self):
     6         print('子类方法')
     7 s = Man()
     8 s.print()
     9 super(Man,s).print()
    10 
    11 输出:
    12 子类方法
    13 父类方法
  • __slots__:定义一个特殊的变量,来限制该class实例能添加的属性
    1 class People(object):
    2     __slots__ = ('name','age')
    3 s = People()    #创建新的实例
    4 s.name = 'jcak'    #绑定属性
    5 s.age = 18
    6 #s.score = 90    #再添加属性时得到AttributeError的错误
  • @property装饰器:把一个方法变成属性调用的。单个getter为可读,再定义.setter属性为可读写。
     1 #用@property给一个Screen对象加上width和height属性,以及一个只读属性resolution
     2 class Screen(object):
     3     @property
     4     def width(self):
     5         return self._width
     6     @width.setter
     7     def width(self,input_width):
     8         self._width = input_width
     9     @property
    10     def height(self):
    11         return self._height
    12     @height.setter
    13     def height(self,input_height):
    14         self._height = input_height
    15     @property
    16     def resolution(self):
    17         return self._width*self.height
    18 s = Screen()
    19 s.width = 1024
    20 s.height = 768
    21 print('resolution =', s.resolution)
    22 if s.resolution == 786432:
    23     print('测试通过!')
    24 else:
    25     print('测试失败!')
    26 
    27 输出:
    28 resolution = 786432 
    29 测试通过!
  • 定制类:形如__xxx__的变量或者函数名来定制类
    • __str__、__call__、__dco__、__dict__、__class__    
       1 class Student(object):
       2     '''描述类信息'''
       3     def __init__(self, name):
       4         self.name = name
       5 
       6     def __str__(self):
       7         return 'Student Object (name:%s)' % self.name
       8 
       9     def __call__(self, *args, **kwargs):
      10         return '实例对象s +()直接运行'
      11 
      12 s = Student('jack')
      13 print(s)    #默认输出_str__中返回的内容
      14 print(s.__doc__)     #输出描述类信息
      15 print(s.__module__)  #当前操作对象所在的模块
      16 print(s.__class__)    #当前操作对象的类
      17 print(s())    #对实例直接调用,返回call的内容
      18 # print(Student.__dict__)   #以字典形式返回当前类中所有对应的关系
      19 print(s.__dict__)
      20 
      21 输出:
      22 Student Object (name:jack)
      23 描述类信息
      24 __main__
      25 <class '__main__.Student'>
      26 实例对象s +()直接运行
      27 {'name': 'jack'}

       

    • __iter__
       1 class Cycle():
       2     def __init__(self):
       3         self.a,self.b = 0,1
       4     def __iter__(self):    #返回一个迭代对象
       5         return self
       6     def __next__(self):    #获取下一个值
       7         self.a,self.b = self.a+self.b,self.b
       8         if self.a > 4:
       9             raise StopIteration
      10         return self.a
      11 
      12 for n in Cycle():
      13     print(n)
      14 
      15 输出:
      16 1
      17 2
      18 3
      19 4

       

    • __getitem__、__setitem__(设置)、__delitem__(删除)
       1 class Cycle():
       2     def __getitem__(self, i):    #返回索引
       3         a,b = 1,1
       4         for x in range(i):
       5             a,b = a+b,b
       6         return a
       7 
       8 print(Cycle()[3])
       9 class Cycle(): #q求切片
      10     def __getitem__(self,n):
      11         start = n.start
      12         stop = n.stop
      13         l = []
      14         a,b =1,1
      15         for x in range(stop):
      16             if x >= start:
      17                 l.append(a)
      18             a,b = b,a+b
      19         return l
      20 print(Cycle()[1:4])
      21 
      22 输出:
      23 3
      24 [1, 2, 3]
    • __getattr__:当调用的属性不存在时,会从getattr获取属性,并返回值,要让class只响应特定的几个  属性,我们就要按照约定,抛出AttributeError的错误
      1 语法:
      2 getattr(object, name[, default])
      3 
      4 object -- 对象
      5 name -- 字符串,对象属性。
      6 default -- 默认返回值,如果不提供该参数,在没有对应属性时,将触发 AttributeError。
      1 class Student(object):
      2 
      3     def __getattr__(self, attr):
      4         if attr=='age':
      5             return lambda: 25
      6         raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)

       

    • __setattr__:设置属性值,该属性必须存在
       1 语法:setattr(object,name,value)    对象;对象属性;属性值。
       2 
       3 class Num():
       4     foo = 1
       5 a = Num()
       6 print(getattr(a,'foo')) #获取属性的值
       7 setattr(a,'foo',8)  #设置属性的值
       8 print(a.foo)
       9 
      10 输出:
      11 1
      12 8

       

  • 枚举类
     1 #@unique装饰器可以帮助检查保证没有重复值
     2 from enum import Enum, unique
     3 @unique
     4 class Weekday(Enum):
     5     Sun = 0 # Sun的value被设定为0
     6     Mon = 1
     7 
     8 day = Weekday.Mon
     9 print(day.value)    #使用value的值或得枚举常量
    10 #----*----
    11 12 Month = Enum('Month', ('Jan', 'Feb'))
    13 for name, member in Month.__members__.items():
    14     print(name, '=>', member, ',', member.value)
    15 print(Month.Jan.value)
    16 
    17 输出:
    18 1
    19 #----*----
    20 Jan => Month.Jan , 1
    21 Feb => Month.Feb , 2
    22 1

     

  • type():可用来创建一个class对象,需传入的三个参数
  1. class的名称
  2. 继承的父类集合,注意Python支持多重继承,如果只有一个父类,使用tuple的单元素写法(后加逗号)
  3. class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上  
     1 def fn(self,name = 'World'):
     2     print('Hello,%s' %name)
     3 H = type('Hello',(object,),dict(hello = fn))    # H 最好与 Hello 写一样防止混淆
     4 # class Hello(object):
     5 #     def hello(self, name='world'):
     6 #         print('Hello, %s.' % name)
     7 h = H()
     8 h.hello()
     9 print(type(H))
    10 print(H.__name__)
    11 
    12 输出:
    13 Hello,World
    14 <class 'type'>
    15 Hello

     

  • Metaclass:元类,metaclass允许创建类或者修改类,类相当于metaclass创建的实例(内容较复杂,先行省略!!!)

 

  • __name__ 与 __main__:python的文件有两种使用的方法,一是直接作为脚本执行,二是import到其他的python脚本中被调用(模块重用)执行。if __name__ == 'main': 的作用就是控制这两种情况执行代码的过程,在if __name__ == '__main__': 下的代码只有在第一种情况下(即文件作为脚本直接执行)才被执行,而import到其他脚本中是不会被执行的。每个python模块都包含内置的变量__name__,当运行模块被执行的时候,__name__等于文件名(包含了后缀.py);如果import到其他模块中,则__name__等于模块名称(不包含后缀.py)。而“__main__”等于当前执行文件的名称(包含了后缀.py)。

转载于:https://www.cnblogs.com/liqiongming/p/10159186.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值