Python_day07_函数结尾_面向对象

函数(继day06)

嵌套函数定义

# 测试嵌套函数(内部函数) 在你函数内部定义函数
def f1(): # 外部函数
    print('f1 running ......')
    def f2(): # 此时f2()函数定义在了f1()里面 内部函数 嵌套函数 只能在f1()内使用 外部无法使用
        print('f2 running ......')
    f2()

f1()

# 嵌套函数一般在什么情况下使用呢?
# 1. 封装 - 数据隐藏 外部无法访问'嵌套函数'
# 2. 贯彻DRY(Do not Repeat Yourself)原则
# 3. 闭包

def printChineseName(name,familyname):
    print('name:',familyname,name)
def printEnglistName(name,familyname):
    print('name:',name,familyname)

def printName(isChinese,name,familyname):
    def inner_print(a,b): # 没有必要在外面定义
        print('{0} {1}'.format(a,b))
    if isChinese:
        inner_print(familyname,name)
    else:
        inner_print(name,familyname)

printName(1,'SH','G')
printName(0,'SH','G')

结果输出:

f1 running ......
f2 running ......
G SH
SH G

nonlocal关键字

nonlocal 用来声明外层的局部变量
global 用来声明全局变量

# 测试nonlocal global关键字的用法

a = 100
def outer():
    b = 10
    def inner():
        nonlocal b # 声明外部函数的局部变量
        print('inner:',b) # 10
        b = 20
        print('inner:', b) # 20
        global a # 声明全局变量
        a = 200
    inner()
    print('外部函数:',b) # 20

outer()
print('a = ',a) # 200

LEGB规则

Python在查找一个’名称’时,是按照LEGB规则查找的:
Local -->Enclosed --> Global --> Built in

  • Local : 指的就是函数或者类的方法内部
  • Enclosed : 指的是嵌套函数(一个函数包裹另一个函数,闭包)
  • Glocal : 指的是模块中的全局变量
  • Built in 指的是Python为自己保留的特殊名称
# 测试LEGB

print(str(30)) # 30
# str = 'global'
def outer():
    # str = 'outer'
    def inner():
        # str = 'inner'
        print(str)
    inner()

outer()
输出:
30
<class 'str'>

面向对象编程

面向对象(OOP)编程思想主要是针对大型软件设计而来。支持 继承 多态 封装。面向对象编程将数据和操作数据相关的方法封装到对象中,组织代码和数据的方式更加接近人的思维,从而将大大提高了编程的效率。Python中一切皆对象 包括我们学习的数据类型 函数等都是对象。

面向对象和面向过程区别

面向过程是通过过程来组织程序,更加关注’程序的逻辑流程’ 是一种执行者思维,按步骤实现,适合编写小规模的程序。
面向对象是通过对象来组织程序,'设计者’思维模式,适合编写大规模程序。
总结: 宏观上使用面向对象把握,微观处理上仍然是面向过程。

对象的进化

简单数据 – 数组 – 结构体 – 对象
第一个面向对象的例子:

class Student: # 类名:首字母大写 多个单词采用驼峰原则 self必须位于第一个参数
    # Python中的属性的定义一定要定义到方法里面
    def __init__(self,name,score):
        self.name = name
        self.score = score
    def say_score(self):
        print('分数为:',self.score)

s1 = Student("GSH",20) # 类名直接调用构造方法 按顺序进行给构造函数赋值
s1.say_score()

输出是:

分数为: 20

构造函数__init__

初始化创建好的对象,初始化指的是: ‘给实例属性赋值’
初始化对象 并不是 创建对象
一个Python对象包含如下内容:

  1. id(identity 识别码)
  2. type(对象的值)
  3. value (对象的值)
    - 属性(attribute)
    - 方法(method)

创建对象,我们需要定义构造函数__init__()方法。构造方法用于执行"实例对象初始化工作",即是对象创建后,初始化当前对象的相关属性,无返回值。

说明:

  • 名称固定 必须为: __init__()
  • 第一个参数固定,必须为:selfself指的就是刚刚创建好的实例对象。
  • 构造函数通常用来初始化实例对象的实例属性 如
  def __init__(self,name,score): # 通过类名()调用构造函数
        self.name = name
        self.score = score
  • 通过"类名(参数列表)"来调用构造函数 调用后 将创建好的对象返回给相应的变量。

实例属性

实例属性是从属于实例对象的属性,也称为"实例变量"。

  1. __init__()内定义此代码: self.实例属性名 = 初始值
  2. 在本类其他的方法中 self.实例属性名 进行访问
  3. 创建实例对象后 通过实例对象进行访问:
obj01 = 类名() # 创建对象 调用`__init__()`初始化属性
		obj01.实例属性名 =# 可以给已有的属性赋值,也可以加新属性

实例方法

def 方法名(self[,形参列表])
	函数体
方法的调用格式:
	对象.方法名([实参列表])

说明:

  1. 定义实例方法时,第一个参数必须是self。和前面一样,self指当前的实例对象
  2. 调用实例方法时,不需要也不能给self传参。self由解释器自动传参

别的一些属性:

print(dir(s1)) # 返回所有属性
print(s1.__dict__) # 直观的属性字典
# pass 空语句 什么都不做
class Man:
    pass

print(isinstance(s2,Student)) # True 判断 '对象' 是不是 '指定类型'

类对象

我们前面讲的是类定义格式中,‘class 类名:’ 。 实际上 当执行器执行class语句时,就会创建一个类对象。

class Student:
    pass # 空语句

print(type(Student)) # <class 'type'> 称为:磨具类 所有类的总类
print(id(Student))

Stu2 = Student

s1 = Stu2()
print(s1)

输出:

<class 'type'>
140298265231168
<__main__.Student object at 0x109d52a10>

类对象和类方法

类属性

类属性是从属于’类对象’的属性,也称为’类变量’。由于,类属性从属于类变量,可以被所有实例对象共享。

class 类名:
	类变量名 = 初始值

举例:

class Student:
    company = 'HUAWEI' # 类属性 这是类自己的东西 所以可以用类名调
    count = 0 # 类属性
    def __init__(self,name,score): # 实例属性
        self.name = name
        self.score = score
        Student.count = Student.count + 1
    def say_score(self): # 实例方法
        print('我公司名字是:',Student.company)
        print('分数为:',self.score)

s1 = Student('张三',80)
s1.say_score()
print(Student.company)
s2 = Student('李四',90)
s3 = Student('王五',89)
print('一共创建了',Student.count,'个对象')
print(s1.company)

输出:

我公司名字是: HUAWEI
分数为: 80
HUAWEI
一共创建了 3 个对象
HUAWEI

分析图

类方法

类方法时从属’类对象’的方法。类方法通过装饰器@classmethod来定义
格式:

@classmethod
def 类方法名(cls [,形参列表])
		函数名

要点:

  1. @classmethod必须位于方法上面一行
  2. 都一个cls必须有 cls 就是类对象本身
  3. 调用类方法格式: '类名.类方法名(参数列表)'。参数列表中,不需要也不能给cls传值
  4. 类方法中访问实例属性和实例方法会导致 错误
  5. 子类继承父类方法时,传入cls是子类对象,而非父类对象
    举例:
class Student:
    company = 'GSH' #类属性

    @classmethod # 表述的是类的状态
    def printCompany(cls):
        print(cls.company)

Student.printCompany() # GSH

s1 = Student()
s1.printCompany() # GSH

静态方法

Python中允许定义与’类方法’无关的方法,称为’静态方法’。
静态方法和 在模块中定义的普通函数没有区别,只不过是’静态方法’放到了’类的名字空间里面’,需要通过’类调用’。
静态方法用通过装饰器@staticmethod来定义

@classmethod
def 静态方法名([形参列表]):
		函数体

举例:

# 测试静态方法:

class Student:
    company = 'HUAWEI' #类属性

    @staticmethod
    def add(a,b):
        print('a+b = ',(a+b))

Student.add(1,8) # 调用静态方法

静态方法和类方法分别不是那么清晰 很多人都在混着用。但是注意:

   def __init__(self,name,age):
        self.name = name
        self.age = age

    @classmethod # 表述的是类的状态
    def printCompany(cls):
        print(cls.company)
        # 这里不可以用self调用 因为类方法和静态方法中不能调用实例变量和实例方法 因为对象都不一定进行实例化 都不一定有无法调用
        # print(self.name)

分析图

__del__方法(析构方法)和垃圾回收机制

__del__方法被称为’析构方法’,用于实现对象被销毁时所需的操作。比如: 释放对象占用资源,例如: 打开的文件资源,网络连接等。

# 析构函数
class Person:
    def __del__(self):
        print('销毁对象:',self) # 程序结束时 要把所有对象进行销毁

p1 = Person()
p2 = Person()
del p2
print('程序结束')
print(p1)
# print(p2)

输出:

销毁对象: <__main__.Person object at 0x101650b90>
程序结束
<__main__.Person object at 0x101650450>
销毁对象: <__main__.Person object at 0x101650450>

__call__方法和可调用对象

定义了__call__方法的对象,称为’可调用方法’,即是该对象可以像函数一样被调用。
比如说调用a方法: a(),实际上调用的就是 --> __call__()
就相当于:
加号其实就是调用的__add__()方法

a = 30
b = 50
c = a + b
d = a.__add__(b)

实例:

class SalaryAccount:
    '''工资计算类'''
    def __call__(self,salary): # 相当于重写调用函数
        print('算工资')
        return salary

s = SalaryAccount()
re = s(3200) # 调用函数时赋值
print('工资总数: ',re) # 3200

输出:

算工资
工资总数:  3200
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值