文章目录
- 前言
- 一、嵌套函数(内部函数)
- 二、nonlocal 关键字
- 三、LEGB 规则
- 四、实操作业
- 1、定义一个函数实现反向输出一个整数。比如:输入 3245,输出 5
- 2、编写一个函数,计算下面的数列:
- 3、输入三角形三个顶点的坐标,若有效则计算三角形的面积;如坐标无效,则给出提示
- 4、输入一个毫秒数,将该数字换算成小时数,分钟数、秒数
- 五、面向对象和面向过程区别
- 六、对象的进化
- 七、类的定义
- 八、__init__构造方法
- 九、实例属性和实例方法
- 1、实例属性
- 2、实例方法
- 十、类对象、类属性、类方法、静态方法
- 1、类对象
- 2、类属性
- 3、类方法 @classmethod
- 4、静态方法 @staticmethod
- 5、内存分析实例对象和类对象创建过程
- 十一、__del__方法(析构函数)和垃圾回收机制
- 十二、__call__方法和可调用对象
前言
本文为7月2日Python基础学习笔记,分为十二个章节:
- 嵌套函数(内部函数);
- nonlocal 关键字:用于声明外层局部变量;
- LEGB 规则;
- 实操作业;
- 面向对象和面向过程区别;
- 对象的进化;
- 类的定义;
- __init__构造方法
- 实例属性和实例方法;
- 类对象、类属性、类方法、静态方法;
- __del__方法(析构函数)和垃圾回收机制;
- __call__方法。
一、嵌套函数(内部函数)
在函数内部定义的函数。
在以下情况下使用:
- 封装 - 数据隐藏: 外部无法访问“嵌套函数;
- 在函数内部避免重复代码:
def printChinesename(name, familyName):
print("{0} {1}".format(familyName, name))
def printEnglishname(name, familyName):
print("{0} {1}".format(name, familyName))
# 使用 1 个函数代替上面的两个函数
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(True, "小七", "高")
printName(False, "Donald", "Trump")
>>> 高 小七
>>> Donald Trump
- 闭包。
二、nonlocal 关键字
# 使用 nonlocal 声明外层局部变量
a = 100
def outer():
b = 10
def inner():
nonlocal b # 声明外部函数的局部变量
print("inner b: ", b)
b = 20
global a
a = 1000
inner()
print("outer b: ", b)
outer()
print("a: ", a)
>>> inner b: 10
>>> outer b: 20
>>> a: 1000
三、LEGB 规则
Python 查找名称的规则:
Local–>Enclosed–>Global–>Built in
- Local: 函数或者类的方法内部;
- Enclosed: 嵌套函数;
- Global: 全局变量;
- Built in: Python 为自己保留的特殊名称。
# 测试 LEGB
str = "global"
def outer():
str = "outer"
def inner():
str = "inner"
print(str)
inner()
outer()
# 依次注释掉 str = "inner", str = "outer", str = "global", 得到的结果如下
>>> inner
>>> outer
>>> global
>>> <class 'str'>
四、实操作业
1、定义一个函数实现反向输出一个整数。比如:输入 3245,输出 5
# 定义一个函数实现反向输出一个整数
def Reverse(n):
s = str(n)
print("该整数的反向整数为 {0}".format(int(s[::-1])))
n = input("输入一个整数:", )
Reverse(n)
>>> 输入一个整数:1234
>>> 该整数的反向整数为 4321
2、编写一个函数,计算下面的数列:
# 编写一个函数,计算下面的数列:m(n) = 1/2 + 2/3 +……+n/(n+1)
def factorial(n):
if n == 1:
return 1/2
else:
return n/(n+1) + factorial(n-1)
result = factorial(3)
print(result)
>>> 1.9166666666666665
3、输入三角形三个顶点的坐标,若有效则计算三角形的面积;如坐标无效,则给出提示
def triangleArea(c):
x = []
y = []
# 将列表 c 中的元素分别放到 x、y 列表中
for i in range(len(c)):
if i%2 == 0:
x.append(c[i])
else:
y.append(c[i])
return abs(x[0] * (y[1]-y[2]) + x[1] * (y[2]-y[0]) + x[2] * (y[0]-y[1]))/2
c = []
for i in range(6):
s = input("依次输入三个顶点的坐标(以 Q 或 q 结束):")
if s.upper() == 'Q':
print("录入完成,退出")
break
c.append(float(s))
else:
print("已录入三个顶点的坐标")
print("三角形面积为:{0}".format(triangleArea(c)))
依次输入三个顶点的坐标(以 Q 或 q 结束):0
依次输入三个顶点的坐标(以 Q 或 q 结束):1
依次输入三个顶点的坐标(以 Q 或 q 结束):0
依次输入三个顶点的坐标(以 Q 或 q 结束):0
依次输入三个顶点的坐标(以 Q 或 q 结束):1
>>> 已录入三个顶点的坐标
>>> 三角形面积为:0.5
4、输入一个毫秒数,将该数字换算成小时数,分钟数、秒数
def msToother(a):
s = a/1000
m = s/60
h = m/60
return s, m, h
a = float(input("输入一个毫秒数:"))
print("秒数为 {0:.2e},分钟数为 {1:.2e},小时数为 {2:.2e}".format(msToother(a)[0], msToother(a)[1], msToother(a)[2]))
>>> 输入一个毫秒数:2234
>>> 秒数为 2.23e+00,分钟数为 3.72e-02,小时数为 6.21e-04
五、面向对象和面向过程区别
- Procedure Oriented:
- 更加关注程序的逻辑流程;
- 执行者思维;
- 适合编写小规模的程序。
- Object Oriented:
- 更加关注软件中对象之间的关系;
- 设计者思维;
- 适合编写大规模的程序。
六、对象的进化
简单数据(30、40)→ 数组([20, 30, 40])→ 结构体(不同类型的数据放到一起)→ 对象(更复杂的逻辑)
class Student:
company = "SANY" # 类属性
count = 0 # 类属性
def __init__(self, name, score): # 构造方法第一个参数必须为 self
self.name = name # 实例属性
self.score = score # 实例属性
Student.count += 1
def say_score(self): # 实例方法
print("我的公司:", Student.company)
print(self.name, "的分数是:", self.score)
s1 = Student("小李", 100) # #s1 是实例对象,自动调用__init__()方法
s1.say_score()
>>> 我的公司: SANY
>>> 小李 的分数是: 100
七、类的定义
把对象比作一个饼干,类就是制造这个饼干的模具。
- 类定义数据类型的属性(数据)和方法(行为);
- 类将行为和状态打包在一起;
- 方法代码是共享的,属性数据不共享: 从一个类创建对象时,每个对象会共享这个类的行为(类中定义的方法),但会有自己的属性值(不共享状态);
八、__init__构造方法
一个 Python 对象包含如下部分:
- id;
- type;
- value:
- 属性(attribute);
- 方法(method)。
需要定义构造函数 __init__() 以创建对象。构造方法用于执行实例对象的初始化工作,即对象创建后,初始化当前对象的相关属性,无返回值。 要点如下:
- 名称必须为 __init__();
- 第一个参数固定,必须为:self;
九、实例属性和实例方法
1、实例属性
- 定义:
self.实例属性名 = 初始值
- 访问:
self.实例属性名
- 通过实例对象访问:
a = Student() # 创建对象,调用__init__()初始化属性
a.score = 100 # 可以给已有属性赋值,也可以新加属性
2、实例方法
- 定义: 第一个参数必须为 self;
- 调用: 不需要也不能给 self 传参。 self 由解释器自动传参。
十、类对象、类属性、类方法、静态方法
1、类对象
- 测试类对象的生成:
class Student:
pass # 空语句
print(type(Student))
print(id(Student))
>>> <class 'type'>
>>> 1294042166464
2、类属性
类属性从属于类对象,可以被所有实例对象共享。
3、类方法 @classmethod
从属于“类对象”的方法。类方法通过装饰器**@classmethod** 来定义。要点如下:
- @classmethod 必须位于方法上面一行;
- 第一个 cls 必须有;cls 指“类对象”本身
- 条用格式:类名.类方法名(参数列表)。参数列表中,不需要也不能给 cls 传值;
- 类方法中访问实例属性和实例方法会报错;
class Student:
company = "SANY" # 类属性
@classmethod
def printCompany(cls):
print(cls.company)
Student.printCompany()
>>> SANY
4、静态方法 @staticmethod
==Python 中允许定义与“类对象”无关的方法,称为“静态方法”。==要点如下:
- @taticmethod 必须位于方法上面一行;
- 调用格式: 类名.静态方法名(参数列表);
- 静态方法中访问实例属性和实例方法会报错。
- 静态方法使用测试:
class Student:
company = "SANY"
@staticmethod
def add(a, b):
print("{0} + {1} = {2}".format(a, b, (a+b)))
return a + b
Student.add(20, 30)
>>> 20 + 30 = 50
5、内存分析实例对象和类对象创建过程
- 类的整个创建过程:
class Student:
company = "SANY" # 类属性
count = 0 # 类属性
# 实例属性
def __init__(self, name, score):
self.name = name # 实例属性
self.score = score # 实例属性
Student.count += 1
# 实例方法
def say_score(self):
print("我的公司:", Student.company)
print(self.name, "的分数是:", self.score)
s1 = Student("小李", 100) #s1 是实例对象,自动调用__init__()方法
s1.say_score()
print('一共创建{0}个 Student 对象'.format(Student.count))
十一、__del__方法(析构函数)和垃圾回收机制
- 用于实现对象被销毁时所需的操作,如,释放对象占用的资源;
- Python 实现自动的垃圾回收, 当对象没有被引用时(引用计数为 0),由垃圾回收器调用__del__方法。
class Person:
def __del__(self):
print("销毁对象{0}".format(self))
p1 = Person()
p2 = Person()
del p2
print("程序结束")
>>> 销毁对象<__main__.Person object at 0x0000020D6A9BB430>
>>> 程序结束
>>> 销毁对象<__main__.Person object at 0x0000020D6A9BB010>
十二、__call__方法和可调用对象
定义了__call__方法的对象,称为可调用对象,即该对象可以像函数一样被调用。
class SalaryAccount:
'''计算工资'''
def __call__(self, salary):
print("计算中……")
yearSalary = salary * 12
daySalary = salary//22.5
hourSalary = daySalary//8
return dict(yearSalary=yearSalary, daySalry=daySalary, hourSalary=hourSalary)
s = SalaryAccount()
print(s(30000))
>>> 计算中……
>>> {'yearSalary': 360000, 'daySalry': 1333.0, 'hourSalary': 166.0}