[Python][华为云Python编程创造营][学习笔记][06_类与对象]

网友投稿 543 2022-05-30

1,面向对象和面向过程

1.1,两种思维方式

面向对象和面向过程是程序中两种常见的思维方式。

1.1.1,面向过程

- 面向过程:把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

- 优点:将复杂的问题流程化,进而简单化。

- 缺点:扩展性差。

1.1.2,面向对象概述

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

[Python][华为云Python编程创造营][学习笔记][06_类与对象]

- 面向过程:把计算机程序视为一系列的命令集合,即一组函数的顺序执行。为了简化程序设计,面向过程把函数继续切分为子函数,即把大块函数通过切割成小块函数来降低系统的复杂度。

- Python中,所有数据类型都可以视为对象,当然也可以自定义对象。自定义的对象数据类型就是面向对象中的类(Class)概念。

- 面向对象:核心是对象二字,特征和技能的结合体。

- 优点:可拓展性高。

- 缺点:编程复杂度高。

- 应用场景:用户需求经常变化,互联网应用,游戏,企业内应用等。

1.1.3,把大象装进冰箱

2,类和对象

- 类:类作为设计蓝图来创建对象的代码段,它描述了对象的特征,该对象具有什么样的属性,怎样使用对象完成一些任务,它对事件进行怎样的响应等。

- 对象:对象是类的一个实例,通常通过调用类的一个构造函数来创建它。

3,面向对象中的术语

- 封装:封装是一个概念,它的含义是把方法、属性、事件集中到一个统一的类中,并对使用者屏蔽其中的细节。

- 继承:继承是一种创建类的方法,在现有类(被继承的类)基础上,进行拓展生成新的类,被称为子类。被继承的类成为父类、基类、超类。

- 多态:一个同样的函数对于不同的对象可以具有不同的实现。

4,Python中的面向对象

- Python是一门面向对象的编程语言,语言中内建了面向对象的特征。在Python中万物皆对象。

- Python支持多继承。

- Python创建类的方式如下:

class 类名(父类):  # class关键字声明类,父类可以是多个,默认继承object

'''类说明文档'''

...类体...

4.1,继承(1)

- 编写了一个名为Animal的class,有一个run()方法可以直接打印:

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

- 当我们需要编写Dog和Cat类时,就可以直接从Animal类继承:

class Dog(Animal): pass class Cat(Animal): pass dog=Dog() dog.run() # Animal is running... cat=Cat() cat.run() # Animal is running...

对于Dog来说,Animal就是它的父类,对于Animal而言,Dog就是它的子类,Cat和Dog类似。

4.2,继承(2)

- 继承还可以一级一级地继承下来

4.3,多态性:子类中定义新方法

- 事实上,Python的多态性就体现在通过覆盖父类的方法来实现,在运行时根据传递的对象引用,来调用相应的方法。Python默认是多态的。

class Animal: def run(): raise AttributeError("子类必须实现这个方法") class People(Animal): def run(self): print("人正在走") # 人正在走 class Dog(Animal): def run(self): print("狗在走") # 狗在走 class Cat(Animal): def run(self): print("猫在走") # 猫在走 p=People() p.run() d=Dog() d.run() c=Cat() c.run()

4.4,私有化

- 默认情况下,属性在Python中都是"public",类所在模块和导入了类所在模块的其他模块都可以访问到。如果类中的某些属性不想被外界访问或者继承可以对其私有化。

- 模块级的私有化:在属性或方法前加上一个下划线即可。防止模块的属性用"from mymodule import *"来加载,它只可以在本模块中使用。

- 完全私有化:只能自己访问。在方法或属性前加双下划线。(Python中的完全私有化是一个假的私有化。它的作用其实是将之前的属性或方法名改为了'_类名._属性/方法')。

4.5,Python对于封装性的看法

- 设计封装的逻辑往往要耗费一定的精力,并且会导致代码更加长不易读等等。

- Python的语言风格没有特别强调封装性。它主张程序员自己通过更加严谨的方式组织程序以避免出错,而不是通过在语言层面实现封装达到这一点。

- 但是,在Python中仍然可以实现对象的(非严格意义上的)封装。

4.6,对象的封装性(1)

- 例如在High_school_student类中,虽然数据已经被封装在类里面,但是我们还是可以通过外部访问其中的变量。我们可以在外部对age进行修改。

class High_school_student(): def __init__(self): self.age=18.0 self.sex='M' student_a=High_school_student() print(student_a.age) # 18.0 student_a.age=28.0 print(student_a.age) # 28.0

4.7,对象的封装性(2)

- 如果我们希望某些内部属性不被外部访问,我们可以在属性名称前加上两个下划线"__",表示将该属性成员私有化,该成员在内部可以被访问,但是在外部是不能够访问的。

class High_school_student(): def __init__(self): self.__age=18.0 self.__sex='M' student_a=High_school_student() print(student_a.__age) # AttributeError: 'High_school_student' object has no attribute '__age'

4.8,对象的封装性(3)

- 成员私有化并不是代表完全不能够从外部访问成员,而是提高了访问的门槛,防止意外或者随意改变成员,引发错误。我们仍然可以通过_类名+私有变量,对变量进行访问。

class High_school_student(): def __init__(self): self.__age=18.0 self.__sex='M' student_a=High_school_student() student_a.__age=18.8 print(student_a._High_school_student__age) # 18.0 print(student_a.__age) # 18.8

4.9,对象的封装性(4)

- 成员私有化不仅包括属性的私有化,也包括了方法的私有化,在方法名称前加上__(两下划线)也可以使得函数只能被内部访问,不能够被外部访问:

class High_school_student(): def __init__(self): self.age=18.0 self.sex='M' def __missing_detecting(self): if self.age=='': print("This is a missing value!") else: print("This is not a missing value!") student_a=High_school_student() student_a.__missing_detecting()

5.0,给对象添加不存在的属性和方法

- 在Python中实例化对象以后,动态的添加类的属性和方法同样会影响对象。

- 动态的属性和方法也可以直接添加在对象上。添加在对象上不会反过来影响类。

class Person(object): def __init__(self,age,name): self.age=age self.name=name p1=Person(18,'zhangsan') def eat(self): print("%s吃%s"%(self.name,self.food)) Person.food="鸡蛋" Person.eat=eat p1.eat()

5.1,面向对象-函数与方法

- 函数:函数是封装了一些独立的功能,可以直接调用,能将一些数据(参数)传递进去进行处理,然后返回一些数据(返回值),也可以没有返回值。可以直接在模块中进行定义使用。

- 方法:方法和函数类似,同样封装了独立的功能,但是方法是只能依靠类或者对象来调用的,表示针对性的操作。

- 区别:函数在Python中独立存在,可直接使用的,而方法是必须被别人调用才能实现。静态方法除外(与类和对象无关,通过类名和对象名均可被调用,属函数)。

5.2,实例方法、静态方法与类方法

- 实例方法,第一个参数为self,调用时需要传递实例给self。

- 静态方法,和类有关,但是在使用时并不需要类或者实例本身(和函数类似)。

通过@staticmethod实现

class C(): @staticmethod def f(): print("HuaweiCloud") C.f() # HuaweiCloud,静态方法无需实例化 hw=C() hw.f() # HuaweiCloud,实例化后调用也可以

- 类方法,第一个参数cls,调用时需要传递类型给类方法。对应的函数不需要实例化,不需要self参数,但第一个参数需要是表示自身类的cls参数,可以用来调用类的属性。

通过@classmethod实现

class A(): bar = 1 def func1(self): print("huawei") @classmethod def func2(cls): print("huawei-classmethod") print(cls.bar) cls().func1() A.func2() # 输出结果 # huawei-classmethod # 1 # huawei

5,魔法方法

魔法方法是指Python内部已经包含的,被双下划线所包围的方法(__init__),在面向对象的Python中,这些方法适用范围广泛,且功能强大。

5.1,常用魔法方法(1)

- __new__(cls[,...]):创建实例时首先调用的方法(构造方法)。

- __init__(self[,...]):对象初始化方法(new方法返回对象后,调用init方法进行属性的初始化)。

new相较于init使用较少。

new可用于单例模式。

class Employee: def __new__(cls): print("__new__ magic method is called") inst=object.__new__(cls) return inst def __init__(self): print("__init__ magic method is called") self.name="Satya" emp=Employee() print(emp) # 输出结果 # __new__ magic method is called # __init__ magic method is called

5.2,常用魔法方法(2)

- __del__(self):析构方法,当实例化对象被彻底销毁时调用(实例化对象的所有指针都被销毁时被调用)。

- __len__(self):定义当被len()调用时的操作。

- len(obj)

- __bool__(self):定义当被bool()调用时的行为,应该返回True或者False。

l=[1,2,3,4] print(l.__len__()) # 4 r=1>2 print(r.__bool__()) # False

5.3,常用魔法方法(3)

- __str__(self):定义当被str()调用时的操作。

默认返回对象信息。

print对象时会被执行。

str()用于将值转化为适合人们阅读的形式。

- __repr(self):定义当被repr()调用时的行为。

repr()用于将值转化为供解释器读取的形式。

class myclass: def __init__(self): self.name="Raj" self.age=21 def __str__(self): return "name : {} age : {}".format(self.name, self.age) def __repr__(self): return {"name":self.name, "age":self.age} obj = myclass() print(obj.__str__()) # name : Raj age : 21 print(obj.__repr__()) # {'name': 'Raj', 'age': 21}

5.4,常用魔法方法(4)

- __getattr__(self,name):定义当用户试图获取一个不存在的属性时的行为。

- __setattr__(self,name,value):定义当一个属性被设置时的行为。

- __getattribute__(self,name):定义当该类的属性被访问时的行为。

访问对象属性或者方法时,首先被调用的方法。

# getattr() class A(): a = 5 def __init__(self,x): self.x = x def hello(self): return "hello func" a = A(10) print(getattr(a,"x")) # a.x,10 print(getattr(a,"y",18)) # a.y,当不存在时返回第三个参数作为默认值,18 print(getattr(a,"hello")()) # a.hello(),hello func print(getattr(A,"a")) # A.a,5 # __getattr()__与__getattribute()__ class A(object): ''' 从输出结果得知,在获取对象属性时, __getattribute()__ 一定被调用,不管属性存不存在, 首先都会调用。如果碰到 a.y 这种不存在对象时, __getattribute()__ 会找不到,这时再 调用 __getattr()__ ,可以通过这个方法设置属性不存在时的默认值。 ''' def __init__(self,x): self.x=x def hello(self): return "hello func" def __getattr__(self,item): print("in __getattr__") return 100 def __getattribute__(self, item): print("in __getattribute__") return super(A,self).__getattribute__(item) a = A(10) print(a.x) print(a.y) # 输出结果 # in __getattribute__ # 10 # in __getattribute__ # in __getattr__ # 100

5.5,Python类中的内置属性

- __dict__:类的属性(包含一个字典,由类的数据属性组成)。

- __doc__:类的文档字符串。

- __name__:类名。

- __module__:类定义所在的模块

类的全名是'__main__.className',如果类位于一个导入模块mymod中,那么className.__module__等于mymod。

- __bases__:类的所有父类构成元素(包含了一个由所有父类组成的元组)。

# __dict__ class A: a = 1 b = 2 def __init__(self): self.s = "hello world" print(A.__dict__) # 输出结果 # {'__module__': '__main__', 'a': 1, 'b': 2, # '__init__': , # '__dict__': , # '__weakref__': , # '__doc__': None} # __doc__ import string print(string.__all__) # ['ascii_letters', 'ascii_lowercase', 'ascii_uppercase', # 'capwords', 'digits', 'hexdigits', 'octdigits', 'printable', # 'punctuation', 'whitespace', 'Formatter', 'Template']

Python

版权声明:本文内容由网络用户投稿,版权归原作者所有,本站不拥有其著作权,亦不承担相应法律责任。如果您发现本站中有涉嫌抄袭或描述失实的内容,请联系我们jiasou666@gmail.com 处理,核实后本网站将在24小时内删除侵权内容。

上一篇:在 TIME_WAIT 状态的 TCP 连接,收到 SYN 后会发生什么?
下一篇:Android开发有关权限(permission)知识点汇总
相关文章