当前位置:网站首页>(4) Function, Bug, Class and Object, Encapsulation, Inheritance, Polymorphism, Copy
(4) Function, Bug, Class and Object, Encapsulation, Inheritance, Polymorphism, Copy
2022-08-02 03:59:00 【stealth rookie】
目录
函数
函数就是执行特定任何以完成特定功能的一段代码
优点:复用代码,隐藏实现细节,提高可维护性,提高可读性便于调试
函数的创建和调用
#例子
def addnum(a,b): #创建
c=a+b
return c
result=addnum(10,20) #调用
print(result) #30
函数的参数传递
1.位置实参:根据形参对应的位置进行实参传递
2.关键字实参:根据形参名称进行实参传递
函数的返回值
函数返回多个值时,结果为元组
1.如果函数没有返回值【函数执行完之后,不需要给调用处提供数据】return可以忽略不写
2.函数的返回值,如果是1个,直接返回类型
3.函数的返回值,如果是多个,返回的结果为元组
函数的参数定义
1.函数定义默认值参数
函数定义时,给形参设置默认值,Arguments need to be passed only when they do not match the default values
def fun(a,b=10):
print(a,b)
#函数调用
fun(100) #100,10 只传一个参数,b采用默认值
fun(20,30) #20,30 传两个值,30把10替换
2.个数可变的位置参数
定义函数时,无法事先确定传递的位置实参个数,可用 * 定义个数可变的位置形参 ,结果为一 个元组
def fun(*args):
print(args)
fun(10) #(10,)
fun(10,20,30) #(10,20,30)
3.个数可变的关键字形参
定义函数时,无法事先确定传递的关键字实参个数,可用 ** 定义个数可变的关键字形参 ,结果为一 个字典
def fun(**args):
print(args)
fun(a=10) #{'a':10}
fun(a=10,b=20,c=30) #{'a':10,'b':20,'c':30}
注:A variable number of positional arguments can only be1个 (不能写成fun(*args,*a));
A variable number of keyword arguments can only be 1个 (不能写成fun(**args,**a));
在一个函数的定义过程中,You can have a variable number of positional arguments and a variable number of keyword arguments at the same time,But a variable number of positional parameters,To be placed before a variable number of keyword parameters.
4.函数参数总结 :
变量的作用域
程序代码能访问该变量的区域
根据变量的有效范围可分为:
1.局部变量
•在函数内定义并使用的变量,只在函数内部有效,局部变量使用global声明,这个变量
就会就成全局变量
2.全局变量
•函数体外定义的变量,可作用于函数内外
递归函数
如果在一个函数的函数体内调用了该函数本身,这个函数就称为递归函数
(1) 递归的组成部分:
递归调用与递归终止条件
(2) 递归的调用过程:
1.每递归调用一次函数,都会在栈内存分配一个栈帧,
2.每执行完一次函数,都会释放相应的空间
(3) 递归的优缺点:
缺点:占用内存多,效率低下
优点:思路和代码简单
Bug
Bug常见类型
常见异常类型
异常处理机制
#举例try...except...else
#如果try块中没有抛出异常,则执行else块;如果try中抛出异常,则执行except块
try:
n1=int(input('输入一个整数:'))
n2=int(input('输入另一个整数:'))
result=n1/n2
except BaseException as e:
print('error')
print(e)
else:
print('结果为',result)
#try...except...else...finally结构
#finally块无论是否发生异常都会被执行,能常用来释放try块中申请的资源
类与对象
There are two kinds of thinking in programming:面向过程、面向对象
(面向过程,things are simple,Linear thinking solves;面向对象,事物复杂,Linear thinking cannot solve it;但是两者并不冲突,是相辅相成的,Object-oriented is easy to grasp the complex relationship between things from a macro perspective,Then use a process-oriented approach to specific processing)
类是多个类似事物组成的群体的统称.
(不同的数据类型属于不同类,使用内置函数type()查看)
Objects are similar distinct instances contained under a class,This instance is called an instance or object.
(例如100、33、56都是intSimilar different instances contained under the class.python中一切皆对象)
类和对象的创建
(1)类的创建
class Student: #Student为类的名称(类名)由一个或多个单词组成,每个单词首字母大写,其余小写
native_place='四川' #直接写在类里的变量,称为类属性
def __init__(self,name,age): #__init__(self)初始化,可以添加属性;name, age为实例属性
self.name=name #self.name称为实例属性,进行了一个赋值,Assign the value of a local variable to an entity property
self.age=age
#实例方法
def info(self):
print('我的名字叫:',self.name,'年龄是:',self.age)
#类方法
@classmethod
def cm(cls):
print ('类方法')
#静态方法
@staticmethod
def sm():
print('静态方法')
#在类中定义的称为方法,在类外定义的称为函数
#函数
def fun():
print('python')
(2)对象的创建
对象的创建又称为类的实例化,With an instance, you can call the content of the class
(一个Student类可以创建N多个Student类的实例对象,每个实例对象的属性值不同)
#创建Student类的实例对象
stu=Student('json',20)
print(stu.name) #实例属性
print(stu.age) #实例属性
stu.info() #实例方法 对象名.方法名()
Student.info(stu) #类名.方法名(类的对象)
类属性、类方法、静态方法
(1) 类属性:类中方法外的变量称为类属性,被该类的所有对象所共享print(Student.native_place)
(2) 类方法:使用@classmethod修饰的方法,使用类名直接访问的方法Student.cm()
(3) 静态方法:使用@staticmethod修饰的方法,使用类名直接访问的方法Student.sm()
动态绑定属性和方法
Python是动态语言,在创建对象之后,可以动态地绑定属性和方法
def show():
print('我是一函数,Functions defined outside the class’)
stu=Student('Jack',20)
stu.gender=’男’#动态绑定属性
print(stu.name,stu.age,stu.gender) #Jack 20 男
stu.show=show #动态绑定方法
stu. show()
封装
面向对象的三大特征:
(1)封装:提高程序的安全性
•将数据(属性)和行为(方法)包装到类对象中.在方法内部对属性进行操作,在
类对象的外部调用方法.这样无需关心方法内部的具体实现细节,thereby isolating the complex
杂度.
•在Python中There is no special modifier for private properties,If the property is not expected to be available outside the class object
访问,前边使用两个“_”下划线.
(2)继承:提高代码的复用性
(3)多态:提高程序的可扩展性和可维护性
#封装
class Student:
def __init__(self,name,age):
self.name=name
self.__age=age #年龄不希望在类的外部被使用,所以加了两个_
def show(self):
print(self.name,self.__age)
stu = Student('张三',20)
stu.show() #张三 20,调用了show()方法,show()输出了name和age,All are internally accessible to both
#在类外访问name与age
print(stu.name) #张三,可访问
# print(stu.__age) #报错,不可访问
#print(dir(stu)) 利用dir可获得stu中所有属性,其中包含了一个_Student__age属性
#print(stu._Student__age) #20,在类的外部,可以通过_Student__age进行访问
继承
1.如果一个类没有继承任何类,则默认继承object
2.python支持多继承
3.定义子类时,必须在子类构造函数中调用父类的构造函数
#继承
class Person(object):
def __init__(self,name,age):
self.name=name
self.age=age
def info (self):
print('姓名:{0},年龄:{1}'.format(self.name,self.age))
#定义子类
class Student(Person):
def __init__(self,name,age,score):
super().__init__(name, age)
self.score=score
#测试
stu=Student('Jack',20,'1001')
stu.info()
#结果 姓名:Jack,年龄:20
多继承
方法重写
1.If the subclass is not satisfied with inheriting a property or method of the superclass,可以在子类中对其(方法体)进行重新编写
2.子类重写后的方法中,可以使用super().xxx()调用父类中被重写的方法
#方法重写
class Person(object):
def __init__(self,name,age):
self.name=name
self.age=age
def info (self):
print('姓名:{0},年龄:{1}'.format(self.name,self.age))
#定义子类
class Student(Person):
def __init__(self,name,age,score):
super().__init__(name, age)
self.score=score
def info (self):
super().info() #This is to call a method of the parent class(Do not use this statement,就不会输出name和age)
print('学号:{0}'.format(self.score)) #这里直接输出了Person类的score
#测试
stu=Student('Jack',20,'1001') #传递实参
stu.info() #调用了Person类里的info()
object类
1.object类是所有类的父类,因此所有类都有object类的属性和方法
2.内置函数dir()可以查看指定对象所有属性
3.object有个__str__()方法,用于返回一个对于“对象的描述”,对应于内置函数str()经常用于print() 方法,帮助我们查看对象的信息,All we often have__str__()进行重写
class Person(object):
def __init__(self,name,age):
self.name=name
self.age=age
def info(self):
print('姓名:{0},年龄:{1}'.format(self.name,self.age))
#重写__str__()
def __str__ (self):
return '姓名:{0},年龄:{1}'.format(self.name,self.age)
p=Person('Jack',20)
print(dir(p)) #查看对象p中的所有属性
print(p) #默认调用__str__()这样的方法
多态
多态就是“具有多种形态”,它指的是:即便不知道一个变量所引用的对象到底是什么类型,仍然可以通过这个变量调用方法,在运行过程中根据变量所引用对象的类型,动态决定调用哪个对象中的方法.
class Animal(object):
def eat(self):
print('动物要吃东西')
class Dog (Animal):
def eat(self):
print('狗吃肉')
class Cat(Animal):
def eat(self):
print('猫吃鱼')
class Person(object):
def eat(self):
print('人吃五谷杂粮')
def fun(animal):
animal.eat ()
fun(Dog())
fun(Cat())
fun(Person())
#Dog、Cat继承于Animal,而Person继承于object,Write a function outside the classfun(),调用fun()not only output“狗吃肉;猫吃鱼”,还输出了“人吃五谷杂粮”,There is no inheritance relationship between these two categories,But still output“人吃五谷杂粮”.因为,传入一个对象,As long as that object contains eat()这个方法,它都会被调用
动态语言与静态语言
静态语言和动态语言关于多态的区别:
1. 静态语言实现多态的三个必要条件:继承、方法重写、父类引用指向子类对象.
2. 动态语言的多态崇尚“鸭子类型”当看到一只鸟走起来像鸭子、游泳起来像鸭子、It also looks like a duck 子,那么这只鸟就可以被称为鸭子.在鸭子类型中,不需要关心对象是什么类型,到底是不是鸭子,只关心对象的行为(方法的功能).
特殊属性和特殊方法
#特殊属性
class A:
pass
class B:
pass
class C(A,B):
def __init__(self,name,age):
self.name=name
self.age=age
class D(A):
pass
#创建C类对象
x=C('Jack',20) #x是C类型的一个实例对象
print(x.__dict__) #实例对象的字典属性
print(C.__dict__)
print('------------------------')
print(x.__class__) #输出对象所属的类,属于<class '__main__.C'>
print(C.__bases__) #C类的父类类型元素,加sJust output all parent classes,不加sjust output one
print(C.__mro__) #类的层次结构
print(A.__subclasses__()) #子类的列表
上述代码的结果为
#特殊方法
#例如
a=10
b=20
c=10+20 #Adds two objects of type integer,实际上的情况是c=a.__add__(b),a调用了__add__()方法与b相加
------------------------------------------------------------------------------------------
class Student:
def __init__(self,name):
self.name=name
def __add__(self, other): #重写__add__(),如果没有这一步,stu1不能与stu2相加
return self.name+other.name
def __len__(self,name):
return len(self.name)
stu1=Student('Jack')
stu2=Student('Lisa')
s=stu1+stu2 #实现了两个对象的加法运算(因为在Student类中编写__add__()特殊方法)
print(s)
print('-----------------------------------')
lst=[1,2,3,4]
print(len(lst)) #len()是内置函数,Used to calculate the length of the list
print(lst.__len__()) #This has the same effect as the above statement
print(len(stu1.name)) #Try to output an objectstu1的长度,报错,因为没有len(),If you want to get this length,可以重写__len__()
以上代码运行结果为
类的浅拷贝与深拷贝
变量的赋值操作:只是形成两个变量,实际上还是指向同一个对象
class CPU:
pass
class Disk:
pass
class Computer:
def __init__(self,cpu,disk):
self.cpu=cpu
self.disk=disk
#(1)变量的赋值
cpu1=CPU()
cpu2=cpu1
print(cpu1,id(cpu1))
print(cpu2,id(cpu2))
#运行结果为
<__main__.CPU object at 0x00000165C193C1C0> 1536551010752
<__main__.CPU object at 0x00000165C193C1C0> 1536551010752
#两者id相同,They point to the same instance object
浅拷贝
python拷贝一般都是浅拷贝,拷贝时,对象包含的子对象内容不拷贝
(源对象与拷贝对象会引用同一个子对象 )
#(2)类有浅拷贝
disk=Disk() #创建一个硬盘类的对象
computer=Computer(cpu1,disk) #创建一个计算机类的对象
print(disk)
#浅拷贝
import copy
computer2=copy.copy(computer)
print(computer,computer.cpu,computer.disk)
print(computer2,computer2.cpu,computer2.disk)
输出的结果为 (The first two arecpu1和cpu2的id)
深拷贝
使用copy模块的deepcopy函数,递归拷贝对象中包含的子对象
(源对象和拷贝对象所有的子对象也不相同 )
#深拷贝
import copy
computer3=copy.deepcopy(computer)
print(computer,computer.cpu,computer.disk)
print(computer3,computer3.cpu,computer3.disk)
输出结果为
边栏推荐
- 14. JS Statements and Comments, Variables and Data Types
- 2. PHP variables, output, EOF, conditional statements
- 1. Beginning with PHP
- Phpstudy installs Thinkphp6 (problem + solution)
- [symfony/finder] The best file manipulation library
- Xiaoyao multi-open emulator ADB driver connection
- js 正则中 replace() 使用
- PHP的几个有趣的打开方式:从基本到变态
- Introduction to PHP (self-study notes)
- hackmyvm-hopper walkthrough
猜你喜欢
解决 Zlibrary 卡死/找不到域名/达到限额问题,Zlibrary最新地址
SQL分类、DQL(数据查询语言)、以及相应SQL查询语句演示
阿里云设置域名解析重定向后,无法使用Chrome访问
hackmyvm-bunny walkthrough
The Error in the render: "TypeError: always read the properties of null '0' (reading)" Error solution
MySql高级 -- 约束
DVWA drone installation tutorial
(1) introduction to Thinkphp6, installation view, template rendering, variable assignment
hackmyvm: juggling walkthrough
Phpstudy installs Thinkphp6 (problem + solution)
随机推荐
阿里云设置域名解析重定向后,无法使用Chrome访问
14. JS Statements and Comments, Variables and Data Types
Pycharm打包项目为exe文件
关于tp的apache 的.htaccess文件
Xiaoyao multi-open emulator ADB driver connection
js预编译 GO 和AO
17.JS条件语句和循环,以及数据类型转换
IP门禁:手把手教你用PHP实现一个IP防火墙
Thread Pool (Introduction and Use of Thread Pool)
MOMENTUM: 2 vulnhub walkthrough
IO流、字节流、字节缓冲流
PHP入门(自学笔记)
Batch replace file fonts, Simplified -> Traditional
(1) introduction to Thinkphp6, installation view, template rendering, variable assignment
解决uni-app 打包H5网站 下载图片问题
[symfony/finder]最好用的文件操作库
Stable and easy-to-use short connection generation platform, supporting API batch generation
v-bind用法:类动态绑定对象 数组 style样式 及函数方法
Introduction to PHP (self-study notes)
IO流、 编码表、 字符流、 字符缓冲流