Python入门与实践(四)面向对象编程(草稿)

目录

 

 

 

 

一、面向对象编程的概念Object Oriented Programming(OOP)

1、面向对象编程的含义:将对象视作程序的基本单元,一个对象包含了数据和操作数据的函数。每个对象都可以接收其他对象发过来的消息,并处理这些消息,计算机程序的执行就是一系列消息在各个对象之间传递。

2、面向过程编程的含义:将计算机程序视作一系列的命令集合,即一组函数的顺序执行。然后为简化程序设计,再将函数切分为子函数,即通过把大函数切割成小函数来降低系统复杂度。

3、二者差别:如果采用面向对象的程序设计思想,我们首选思考的不是程序的执行流程,而是Student这种数据类型应该被视为一个对象,这个对象拥有namescore这两个属性(Property)。如果要打印一个学生的成绩,首先必须创建出这个学生对应的对象,然后,给对象发一个print_score消息,让对象自己把自己的数据打印出来。给对象发消息实际上就是调用对象对应的关联函数,我们称之为对象的方法(Method)。

一个class既包含数据又包含针对数据的方法。

二、类和实例

1、类和实例的关系:类是抽象的模板,实例是根据类创建出的具体的对象,每个对象有相同的方法,但各自的数据可能各不相同。

2、类的定义:

  • 一般用大写开头的名称定义类;
  • (object)为所定义类要继承的类,如果没有合适的继承类就用object类,这是每个类都继承的类(老祖宗?)
class Student(object):
    pass

3、实例的创建:

  • 创建格式:实例名=类名()
>>> bart = Student()
>>> bart
<__main__.Student object at 0x10a67a590>
>>> Student
<class '__main__.Student'>

4、类的__init__方法:

  • 是一个初始化,将该类所必须的属性强制填写进去
  • 第一个参数是self,表示实例自身
class Student(object):

    def __init__(self, name, score):
        self.name = name
        self.score = score
  • 和普通的函数相比,在类中定义的函数只有一点不同,就是第一个参数永远是实例变量self

5、访问限制

(1)对于类内部的参数,以两个下划线_ _开头命名则为私有变量,外部不能够访问;这样做的好处在于保证外部代码不能随意更改对象内部的状态

(2)要注意_ _***_ _是可以访问的,并不是私有变量,而仅开头有两个下划线则为私有变量

(3)当数据被封装为私有变量时,可以在类内部定义接口函数,让外部可以获取或者设定更改内部数据数值;此时该接口函数能够对输入数据进行筛选限制,避免传入无效参数,更加可控

(4)定义单下划线开头的变量时,其仍为公开变量,但是按照约定俗成尽量认作私有变量

(5)事实上,所谓的_ _***私有变量只不过是被更改了变量名,一般是给加上了前缀变成了“_类名_ _***”。这样的变量,实际上还是能够通过更改后的名字访问,但是由于不同python解释其对其更改可能不同,所以不该这样直接访问。

例子:下边的程序看似更改了私有变量,实际上只是在其内部重新定义了一个新的_ _name,并没有更改实际的内部变量_ _name

>>> bart = Student('Bart Simpson', 59)
>>> bart.get_name()
'Bart Simpson'
>>> bart.__name = 'New Name' # 设置__name变量!
>>> bart.__name
'New Name'

“总的来说就是,Python本身没有任何机制阻止你干坏事,一切全靠自觉”

三、继承和多态

1、继承:子类自动拥有父类(基类、超类)的全部方法

  • 可以对父类的方法进行重定义覆盖
  • 无论是抽象的子类与父类之间,还是实例与其抽象类之间,均存在类型从属关系,即:
b = Animal() # b是Animal类型的实例
class Dog(Animal):#Dog是Animal的子类
    pass
c = Dog() # c是Dog类型的实例
>>> isinstance(b, Animal)#b是Animal类型
True
>>> isinstance(c, Dog)#c是Dog类型
True
>>> isinstance(c, Animal)# c也是Animal类型
True
>>> isinstance(Dog, Animal)# Dog也是Animal类型
True
  • 判断是不是某个类型:isinstance()      返回布尔类型

3、多态:

不同的类中定义的相同名义的方法可以直接不加以区分地调用:以下例子中,def run(object)中的object名任给,在调用时只要object包含有run()这个方法就行。

class Animal(object):
    def run(self):
        print('Animal is running...')

class Dog(Animal):
    def run(self):
        print('Dog is running...')

class Cat(Animal):
    def run(self):
        print('Cat is running...')

def running(something):#定义running
    something.run()
    print(isinstance(something,Animal))

class mytest(object):#定义一个非Animal子类的类包含running
    def run(self):
        print('I am running, too.')

running(Animal())
running(Dog())
running(Cat())
running(mytest())

#输出结果
Animal is running...
True
Dog is running...
True
Cat is running...
True
I am running, too.
False

4、关于静态语言与动态语言的差异:???【存疑】

静态语言就必须是同类下方可调用方式,但动态语言只需要保证有个相同的方式就行了,管你是这个类还是那个类?

四、获取对象信息

1、使用type()

  • 通常可以用type(***)来判别其所属class类型
  • 通过import types模块可以具体判断对象的函数类型
>>> import types
>>> def fn():
...     pass
...
>>> type(fn)==types.FunctionType
True
>>> type(abs)==types.BuiltinFunctionType
True
>>> type(lambda x: x)==types.LambdaType
True
>>> type((x for x in range(10)))==types.GeneratorType
True

2、使用isinstance()

isinstance(A,objectB)

判断A是不是B的子类,返回为布尔类型

【一些使用方法】

  • 也可以判别str int 等,类似于type
  • 还能够判别对象是不是多种class中的一种
#isinstance()可以实现type()的功能:
>>> isinstance('a', str)
True
>>> isinstance(123, int)
True
>>> isinstance(b'a', bytes)
True

#还可以判别是不是多种class中的一种:
>>> isinstance([1, 2, 3], (list, tuple))
True
>>> isinstance((1, 2, 3), (list, tuple))
True

3、使用dir()

dir()作用:获得一个对象的所有属性和方法,返回一个list

>>> dir('ABC')
['__add__', '__class__',..., '__subclasshook__', 'capitalize', 'casefold',..., 'zfill']

#对len()函数的使用,其实其内部就是调用了目标对象的__len__方法
>>> len('ABC')
3
>>> 'ABC'.__len__()
3

对对象属性进行的操作:has、get、set

#对对象属性(attribute,attr)的判别分析
#hasattr(obj,'x'):有没有该属性?
#setsttr(obj,'x',***):设定一个属性
#getsttr(obj,'x',***):获取属性
>>> hasattr(obj, 'x') # 有属性'x'吗?
True
>>> obj.x
9
>>> hasattr(obj, 'y') # 有属性'y'吗?
False
>>> setattr(obj, 'y', 19) # 设置一个属性'y'
>>> hasattr(obj, 'y') # 有属性'y'吗?
True
>>> getattr(obj, 'y') # 获取属性'y'
19
>>> obj.y # 获取属性'y'
19

#查找属性时,对于不存在的属性,可以给定返回值
>>> getattr(obj, 'z') # 获取属性'z'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: 'MyObject' object has no attribute 'z'

>>> getattr(obj, 'z', 404) # 获取属性'z',如果不存在,返回默认值404
404
  • 可以通过del ***删除实例或类的属性:
>>> class Student(object):
...     name = 'Student'
...
>>> s = Student() # 创建实例s
>>> print(s.name) # 打印name属性,因为实例并没有name属性,所以会继续查找class的name属性
Student
>>> print(Student.name) # 打印类的name属性
Student
>>> s.name = 'Michael' # 给实例绑定name属性
>>> print(s.name) # 由于实例属性优先级比类属性高,因此,它会屏蔽掉类的name属性
Michael
>>> print(Student.name) # 但是类属性并未消失,用Student.name仍然可以访问
Student
>>> del s.name # 如果删除实例的name属性
>>> print(s.name) # 再次调用s.name,由于实例的name属性没有找到,类的name属性就显示出来了
Student
>>> del Student.name
>>> print(Student.name)
Traceback (most recent call last):
  File "<input>", line 1, in <module>
AttributeError: type object 'Student' has no attribute 'name'

 

 

 

参考链接:

廖雪峰的官方网站-Python教程-面向对象编程

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值