函数实现代码复用

  • 1.函数实现代码复用
    • 1.1函数的定义和调用
    • 1.2函数的参数和返回值
  • 2.面向对象编程
    • 2.1面向对象的基本概念
    • 2.2创建类与对象
    • 2.3属性和方法
    • 2.4构造方法和析构方法
    • 2.5属性和方法的访问控制
    • 2.6继承
    • 2.7多态
    • 2.8封装
    • 2.9单例模式

1.函数实现代码复用

1.1函数的定义和调用

​ 你可以定义一个由自己想要功能的函数,以下是简单的规则:

  • 函数代码块以 def 关键词开头,后接函数标识符名称和圆括号 ()
  • 任何传入参数和自变量必须放在圆括号中间,圆括号之间可以用于定义参数。
  • 函数的第一行语句可以选择性地使用文档字符串—用于存放函数说明。
  • 函数内容以冒号 : 起始,并且缩进。
  • return [表达式] 结束函数,选择性地返回一个值给调用方,不带表达式的 return 相当于返回 None。
#Python 定义函数使用 def 关键字,一般格式如下:
def 函数名(参数列表):函数体#更复杂点的应用,函数中带上参数变量:
def max(a, b):if a > b:return aelse:return ba = 4
b = 5
print(max(a, b))
def print_xing():print("***************************")
def print_text():print("这是一个函数调用实例!")print_xing()
print_text()
print_xing()#运行结果
***************************
这是一个函数调用实例!
***************************

1.2函数的参数和返回值

  • 形参与实参
def max(a,b):if a>b:return aelse:return bx=int(input("请输入一个数x:"))
y=int(input("请再输入一个数y:"))
z=max(x,y)
print("较大数为:",z)

​ 分析这个比较最大数,其中max()函数括号内的a,b就是该函数的形参;而在调用函数时,括号内的x和y则是传递给该函数的实参

  • 必备参数

​ 必备参数须以正确的顺序传入函数。调用时的数量必须和声明时的一样。

​ 调用 print_text()函数,你必须传入一个参数,不然会出现语法错误:

def print_text(x,y):print(x,y)print_text("hello","Final Exam!")print_text("hello")
#运行结果
hello Final Exam!
Traceback (most recent call last):File "D:/pycharm/py代码/Python期末/函数调用.py", line 26, in <module>print_text("hello")
TypeError: print_text() missing 1 required positional argument: 'y'
  • 关键字参数

​ 关键字参数和函数调用关系紧密,函数调用使用关键字参数来确定传入的参数值。

​ 使用关键字参数允许函数调用时参数的顺序与声明时不一致,因为 Python 解释器能够用参数名匹配参数值。

​ 以下实例在函数 fun() 调用时使用参数名:

def fun(discount,price):print("商品折扣:",discount)print("商品价格:",price)return
fun(price=100,discount=0.4)
#运行结果
商品折扣: 0.4
商品价格: 100
  • 默认参数

​ 调用函数时,如果没有传递参数,则会使用默认参数。以下实例中如果没有传入 price 参数,则使用默认值:

def fun(discount,price=100):print("商品折扣:",discount)print("商品价格:",price)return
fun(0.4)
#运行结果
商品折扣: 0.4
商品价格: 100

**值得注意的是,在定义默认值参数的函数时,只能将默认值赋给最右端的参数,否则会出现语法错误。**在Pycharm中早已经出现报错了。

def fun(discount=0.4,price):print("商品折扣:",discount)print("商品价格:",price)return
fun(100)
#运行结果def fun(discount=0.4,price):^
SyntaxError: non-default argument follows default argument
  • 不定长参数

​ 你可能需要一个函数能处理比当初声明时更多的参数。这些参数叫做不定长参数,和上述 2 种参数不同,声明时不会命名。只需在参数列表最右侧增加一个带*的参数,基本语法格式如下:

def 函数名([形参列表] *args):函数体
#例子
def f(x,y,*args):print(x)print(y)print(args)
f(10,9,8,7,6,5,4,3,2,1)
#运行结果
10
9
(8, 7, 6, 5, 4, 3, 2, 1)
  • 函数的返回值

return [表达式] 语句用于退出函数,选择性地向调用方返回一个表达式。不带参数值的 return 语句返回 None。可以返回0个、1个或一组值,以下实例演示了 return 语句的用法:

def fun(discount,price):price=discount*priceprint("商品折扣:",discount)print("商品价格:",price)return price
fun(0.5,100)
#运行结果
商品折扣: 0.5
商品价格: 50.0
  • 匿名函数

​ 所谓匿名,意即不再使用 def 语句这样标准的形式定义一个函数。

  • lambda 只是一个表达式,函数体比 def 简单很多。
  • lambda用于定义简单的、能够在一行内表示的函数,返回一个函数类型;lambda函数能接受任何数量的参数,但只能返回一个表达式,同时只能处理输出的内容,不可包含命令或多个表达式,匿名函数不能直接调用print,因为lambda需要一个表达式。
函数名=lambda[参数列表] : 表达式sum=lambda arg1,arg2:arg1+arg2;
print("total:",sum(20,50))#运行结果
total: 70

2.面向对象编程

2.1面向对象的基本概念

  • 对象

    ​ 现实世界中客观存在的事物称作对象,任何对象都具有各自的特征(属性)和行为(方法)。**对象的特征用数据来表示,称为属性;对象的行为用程序代码实现,称为对象的方法。**总之,任何对象都是由属性和方法组成的。

  • ​ 类是具有相同属性和行为的一组对象的集合,它为属于该类的全部对象提供了统一的抽象描述。任何对象都是某个类的实例。

    用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。

  • 消息

    ​ 一个系统由若干个对象组成,各个对象之间通过消息相互联系,相互作用。消息是一个对象要求另一个对象实施某项操作的请求。发送者发送消息,在一条消息中,需要包含消息的接收者和要求接收者执行某项操作的请求,接收者通过调用相应的方法响应消息,这个过程被不断的重复,从而驱动整个程序的运行。

  • 封装

    ​ 封装是指把对象的数据(属性)和操作数据的过程(方法)结合在一起,构成独立的单元,它的内部信息对外界是隐蔽的,不允许外界直接存取对象的属性,只能通过类提供的外部接口与对该对象实施各项操作,保证了程序中数据的安全性。

    类是数据封装的工具,对象是封装的实现。

  • 继承

    ​ 继承反映的是类与类直接抽象级别的不同,根据继承与被继承的关系,可分为基类和衍类,基类也称为父类,衍类也称为子类,正如"继承"这个词的字面含义一样,子类将从父类那里获得所有的属性和方法,并且可以对这些获得的属性和方法进行改造,使之具有自己的特点。

  • 多态

    ​ 多态是指统一名字方法产生了多种不同的动作行为,也就是不同的对象收到相同的消息时产生不同的行为方式。该多态的概念应用于面向对象程序设计,增强了程序对客观世界的模拟性,使得对象程序具有更好的可读性。

2.2创建类与对象

  • 定义类
    在python中,用class关键字来定义类,定义类的语法格式如下:

    class ClassName:<statement-1>...<statement-N>#应用示例
    class CC:x=10y=20z=30def show(self):print((self.x+self.y+self.z)/3)b=CC()
    b.x=30
    b.show()
    #运行结果
    26.666666666666668
    
  • 对象的创建和使用

    在Python中,用赋值的方式创建类的实例,一般格式为:

    对象名=类名(参数列表)

    创建对象后,可以使用“.”运算符,通过实例来防卫这个类的属性和方法(函数)。实例如上。

2.3属性和方法

  • 类属性和实例属性

    • 类属性

      类属性为所有类对象的实例对象所共有。类属性通常在类体中初始化。对于公有的类属性,在类外可以通过类对象和实例对象访问。

      类的私有属性

      __private_attrs:两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs

      class Person:name='brenden'__age=18
      p=Person()
      print(p.name)
      print(Person.name)
      print(p.__age)#报错,不能在类外通过实例对象访问私有的类属性
      print(Person._age)#报错,不能在类外通过类对象访问私有的类属性
    • 实例属性

      实例属性不需要在类中显示定义,而应该在_ _ init _ _ 构造函数中定义,定义时以"self."作为前缀,实例属性属于特定的实例。所有的实例属性最好在 _ _ init _ _ 中给出。实例属性在内部通过“self.”访问,在外部通过对象实例访问。

      class Student:def __init__(self,name,age,grade):self.name=nameself.age=ageself.grade=gradedef say_hi(self):print('I am a student ,my name is ' ,self.name)s1=Student('王子',21,3)s1.say_hi()
      print(s1.grade)s2=Student('公主',20,2)s2.say_hi()
      print(s2.grade)#运行结果
      I am a student ,my name is  王子
      3
      I am a student ,my name is  公主
      2
      

      上述例子中,Student类中定义了实例属性name,age和grade。s1、s2是Student的两个实例,这两个实例分别拥有自己的属性值,有别于其他对象。实例的属性可以向其他变量一样进行操作。

      s1.grade=s1.grade+1
      
  • 类的方法
    方法是与类相关的函数。方法和函数不同,函数时封装操作的小程序。方法是定义在类内部的函数,并且定义方法与普通函数有所不同。类的方法主要有三种类型:实例方法、类方法和静态方法,不同的方法有不用的使用场景和声明调用形式,不同的方法也具有不同的访问限制。实例方法是属于实例的方法,通过实例名方法名调用,该方法可以访问类属性、实例属性、类方法、实例方法和静态方法。类方法是属于类的方法,可以通过实例名方法名,也可以通过类名方法名调用。类方法不能访问实例属性和实例方法。静态方法是与类实例对象无关的方法,调用形式同类方法类似。

  • 方法的声明和调用

  • 在类的内部,使用def关键字可以为类定义一个方法。与一般函数定义不同,类方法必须包含对象本身的参数,通常为self,且为第一个参数。声明方法的语法格式如下:

    ​ def 方法名(self,[形参列表])

    ​ 函数体

    方法调用的语法格式如下:

    ​ 对象.方法名([参数列表])

    在调用方法时,第一个参数self不需要用户为其赋值,Python自动把对象实例传递给参数self。

  • 实例方法

    实例方法是在类中经常定义的成员方法,它至少有一个参数并且必须以实例对象作为其第一个参数,一般以“self”作为第一个参数。在类外,实例方法只能通过实例对象去调用。

#定义Person类,通过实例调用实例方法
class Person:place = 'jiangxijxau'def getPlace(self):#实例方法return self.placep=Person()
print(p.getPlace())
print(p.place)
#运行结果
jiangxijxau
jiangxijxau
  • 类方法
    类方法不对特定实例进行操作,在类方法中访问实例属性会导致错误。类方法需要用修饰器"@ classmethod"来标识其为类方法。对于类方法,第一个参数必须是类对象,一般以“cls”作为第一个参数,类方法可以通过实例对象和类对象进行访问。

    类方法还有一个用途就是可以对类属性进行修改。

#定义Person类,定义并调用类方法
class Person:place = 'jiangxijxau'@classmethoddef getPlace(cls):return cls.placep=Person()
print(p.getPlace())
print(Person.getPlace())
#运行结果
jiangxijxau
jiangxijxau#定义Person类,定义并修改类属性
class Person:place = 'jiangxijxau'@classmethoddef getPlace(cls):return cls.place@classmethoddef setPlace(cls,place1):cls.place=place1p=Person()
p.setPlace("shanghai")
print(p.getPlace())
print(Person.getPlace())
#运行结果
shanghai
shanghai
  • 静态方法
    静态方法需要通过修饰器“@staticmethod”来进行修饰,静态方法不需要多定义参数。

    #定义Person类,定义并调用静态方法
    class Person:place='jishui'@staticmethoddef getPlace():return Person.place
    print(Person.getPlace())
    #运行结果
    jishui
    

2.4构造方法和析构方法

  • 构造方法

    构造方法 _ _ init _ _ (self,…)在生成对象是调用,可以用来进行一些属性初始化操作,不需要显式去调用,系统会默认执行。构造方法支持重载,如果用户自己没有重新定义构造方法,系统就自动执行默认的构造方法。

    #构造方法并使用示例
    class Person:def __init__(self,name):self.PersonName=namedef sayHi(self):print('大家好,我是{}。'.format(self.PersonName))p=Person('泽冷')
    p.sayHi()
    #运行结果
    大家好,我是泽冷。
    
  • 析构方法
    析构方法 _ _ def _ _ (self) 在释放对象时被调用,支持重载,可以在其中进行一些释放资源的操作,不需要显式去调用

    #构造方法并使用示例
    class Test:def __init__(self):print('构造方法')def __del__(self):print("析构方法")def myf(self):print('调用自定义方法')obj = Test()
    obj.myf()
    del obj#运行结果
    构造方法
    调用自定义方法
    析构方法
    

2.5属性和方法的访问控制

  • 属性的访问控制
    python中没有像C++中public和private这些关键字来区别公有属性和私有属性,它是以属性命名的方式来区别的,如果在属性名前面加了两个下划线 _ _ ,那么表示私有属性,否则为公有属性。如果在方法名前面加了则说明是私有方法。

  • 方法的访问控制
    在类中可以根据需要定义一些方法,定义方法采用def关键字,在类中定义的方法至少会有一个参数,一般以名为“self”的变量作为该参数,而且需要作为第一个参数。

2.6继承

继承用于指定一个类将从其父类获取其大部分或全部功能。用户对现有类进行修改,来创建一个新的类,称为子类或派生类,原有类称为父类或基类。

#面向对象之继承
class Person(object):def __init__(self,name,gender):self.name=nameself.gender=genderprint('person类 __ini()__.','姓名:',self.name)class Student(Person):def __init__(self,name,gender,score):super(Student, self).__init__(name,gender)self.score=scoreprint('Student类 __ini()__.','姓名:',self.name)#“__main__”等于当前执行文件的名称
if __name__=="__main__":person=Person('张三','男')student=Student("李四",'女',100)#运行结果
person类 __ini()__. 姓名: 张三
person类 __ini()__. 姓名: 李四
Student类 __ini()__. 姓名: 李四
  • 多继承
#面向对象之多重继承
class P1():def foo(self):print("p1-foo")
class P2():def foo(self):print("P2-foo")def bar(self):print("P2-bar")
class C1(P1,P2):pass
class C2(P1,P2):def bar(self):print("C2-bar")
class D(C1,C2):pass
if __name__=='__main__':d=D()d.foo()d.bar()
#运行结果
p1-foo
C2-bar

子类可以继承一个父类,也可以继承多个父类,这就是多重继承。多重继承的语法格式如上。

2.7多态

多态即多种形态,在运行时确定其状态,在编译阶段无法确定其类型,这就是多态。

多态性指的是:向不同对象发送同一条消息,不同对象在接收时会产生不同的行为(即方法)。所谓消息,就是调用函数,不同的行为就是指不同的实现,即执行不同的函数。

#不使用多态的面向对象程序实现
class ArmyDog(object):def bite_enemy(self):print('追击敌人')
class DrugDog(object):def track_drug(self):print('追查毒品')
class Person(object):def work_with_army(self,dog):dog.bite_enemy()def work_with_drug(self,dog):dog.track_drug()
person = Person()
person.work_with_army(ArmyDog())
person.work_with_drug(DrugDog())
#运行结果
追击敌人
追查毒品#使用多态的面向对象程序实现
class Dog(object):def work(self):pass
class ArmyDog(Dog):def work(self):print("追击敌人")
class DrugDog(Dog):def work(self):print("追查毒品")
class Person(object):def work_with_dog(self,dog):dog.work()
person = Person()
person.work_with_dog(ArmyDog())
person.work_with_dog(DrugDog())
#运行结果
追击敌人
追查毒品

2.8封装

封装其实分为两个层面,第一个层面的封装:创建类和对象会分别创建两者的名称空间,只能用“类名.”或者“实例名.”的方式去访问里面的属性和方法,这就是一种封装。

第二个层面的封装:类中把某些属性和方法隐藏起来(或者说定义成私有的),只在类的内部使用,外部无法访问,或者留下少量接口(函数)供外部访问。在继承中,如果父类不想让子类覆盖自己的方法,可以将方法定义为私有的。

class A:def fm(self):print('from A')def test(self):self.fm()
class B(A):def fm(self):print('from B')
b=B()
b.test()
#运行结果#运行结果
from B#将fm()定义成私有的,即 _ _ fm (),输出结果就会变成“from A”class A:def __fm(self):print('from A')def test(self):self.__fm()
class B(A):def __fm(self):print('from B')
b=B()
b.test()
#运行结果#运行结果
from A

2.9单例模式

在某些系统中,为了节省内存资源、保证数据内容的一致性,对某些类要求只能创建一个实例,这就是所谓的单例模式。

单例模式是一种常用的软件设计模式,该模式的主要目的是确保对某一个类还有一个实例存在。

在计算机系统中,还有windows的回收站、操作系统的文件夹系统、应用程序的日志对象、数据库的连接池、网站的计数器、web应用的配置对象、应用程序中的对话框、系统中的缓存等常常被设计成单例。

#创建一个全局唯一的实例对象
class Earth(object):__instance = None #定义一个类属性做判断def __new__(cls):if cls.__instance == None:#如果__instance为空证明是第一次创建实例#通过父类的__new__(cls)创建实例cls.__instance=object.__new__(cls)return cls.__instanceelse:#返回上一个对象的引用return cls.__instancea=Earth()
print(id(a))
b=Earth()
print(id(b))
#运行结果#运行结果
1846493173704
1846493173704

在Python中,一个类创建实例是通过调用父类object的 _ _ new _ _ (cls)方法来创建的。我们可以通过重写 _ _ new _ _ (cls)方法去实现类只创建一个实例。

【Python】函数递归调用与面向对象编程总结相关推荐

  1. python3_函数_形参调用方式 / 不定长参数 / 函数返回值 / 变量作用域 / 匿名函数 / 递归调用 / 函数式编程 / 高阶函数 / gobal和nonlocal关键字 / 内置函数

    1.形参的调用方式 1. 位置参数调用 2. 关键词参数调用 原则: 关键词参数调用不能写在位置参数调用的前边 def test1(name, age):print("name:" ...

  2. python归一化 增大差异_简学Python第六章__class面向对象编程与异常处理

    Python第六章__class面向对象编程与异常处理 欢迎加入Linux_Python学习群 群号:478616847 目录: 面向对象的程序设计 类和对象 封装 继承与派生 多态与多态性 特性pr ...

  3. Python基础十五:面向对象编程四:高级特性

    Python基础十五:面向对象编程四:高级特性 Python基础系列内容为学习廖雪峰老师Python3教程的记录,廖雪峰老师官网地址:廖雪峰Python3教程 Author:yooongchun Em ...

  4. androidstudio调用系统相机为什么resultcode一直返回0_函数递归调用?看这文就够了...

    作者 | Cooper Song 责编 | Elle 出品 | 程序人生(ID:coder_life) 我猜,大多数程序员第一次接触函数的递归调用都是在算斐波那契数列某项值的时候,这是函数递归调用最常 ...

  5. python函数递归年龄,python之函数递归

    函数递归调用 在函数内部,可以调用其它函数,如果一个函数在内部调用自身,即是递归调用 为防止无限递归类似于死循环,需要如下: 1.必须要有一个明确的返回值: 2.每次进入更深一层递归时,问题规模应该比 ...

  6. 函数递归调用?看这文就够了!

    作者 | Cooper Song 责编 | Elle 出品 | 程序人生(ID:coder_life) 我猜,大多数程序员第一次接触函数的递归调用都是在算斐波那契数列某项值的时候,这是函数递归调用最常 ...

  7. Python函数递归

    Python函数递归 在函数内部,可以调用其他函数.如果一个函数在内部调用自身本身,这个函数就是递归函数. 递归中可以函数自身调用自身,但是使用时类似于条件循环一样,要有递归的终止条件. 例如使用函数 ...

  8. python函数+定义+调用+多返回值+匿名函数+lambda+高级函数(reduce、map、filter)

    python函数+定义+调用+多返回值+匿名函数+lambda+高级函数(reduce.map.filter) Python 中函数的应用非常广泛,比如 input() .print().range( ...

  9. C语言程序设计 函数递归调用示例

    函数递归调用示例(教材习题5.3,运行结果012345) #include<stdio.h> void fun(int k); void main() {   int w=5;   fun ...

  10. python函数递归 汉诺塔

    4.7 python函数递归 汉诺塔 代码: def hanno(n,A,B,C):global stepif n==1:print('{}->{}'.format(A,C))step +=1e ...

最新文章

  1. Social regularizations
  2. 运动目标检测ViBe算法
  3. springmvc中url-url-pattern /和/*的区别
  4. Calendar使用方法
  5. weblogic 启动项目失败,JMS 队列通过http 方式访问
  6. Shell-通过shell启动Java类中的main方法 + 通过Shell启动jar包
  7. 如果产品经理去卖土豆粉
  8. 下载大文件 不经过php 直接让apache发送文件给客户端 mod_xsendfile
  9. 常见特征检测算法介绍
  10. 【Silverlight】Bing Maps学习系列(九):自定义功能导航条(Custom NavigationBar)
  11. ABAP学习笔记之五-报表的事件 [翱翔云天 ]
  12. 施一公:无论什么学科,最不重要的就是智商
  13. DHCP 报文结构和类型
  14. PUN☀️二、局域网的搭建
  15. lightgbm画决策树方法
  16. 手机启动不了android,安卓手机开不了机,小编教你如何解决安卓智能手机开不了机问题...
  17. 理解分布式一致性:Paxos协议之Multi-Paxos
  18. 朱嘉明出任数字经济领袖班教务长 | 强大导师阵容,虚位以待
  19. JavaScript循环语句for,while,与break,continue配合案例详解
  20. Txt、记事本等文本文件怎么批量插入标题?怎么在指定位置插入新的内容?

热门文章

  1. 2023年中国连锁中餐发展现状分析:小菜园和绿荼餐厅门店数保持稳定增长[图]
  2. 单细胞测序数据的差异表达分析方法总结-single cell differential expression
  3. 工勤人员计算机考试内容,工勤人员人机对话考试已开始
  4. 万网服务器ftp上传出现553 Could not create file
  5. 第七篇:爬虫实战--- 1、破解滑动验证码
  6. Segmentation Fault错误
  7. conda无法更新或安装模块
  8. 如何让两台手机相互远程控制?
  9. springboot 集成 netty-socketio
  10. 软著证书多久可以下来?软著的有效期是多长时间?