目录
目录
一、函数用法和底层分析
(一)嵌套函数(内部函数)
(二)nonlocal关键字
(三)LEGB规则
二、面向对象编程
(一)面向对象和面向过程区别
(二)类的定义
(三)构造函数__init__()
(四)实例属性和实例方法
(五)类对象、类属性、类方法、静态方法
(六)__del__方法(析构函数)和垃圾回收机制
(七)__call__方法和可调用对象
一、函数用法和底层分析
(一)嵌套函数(内部函数)
#测试嵌套函数(内部函数)的定义
def outer():
print("outer running")
def inter01():
print("inter01 running")
inter01()
outer()
1.嵌套函数使用情况:
(1)封装-数据隐藏:外部无法访问“嵌套函数”
(2)降低重复代码
(3)闭包(见后)
def printChineseName(name,familyName):
print("{0} {1}".format(familyName,name))
def printEnglishName(name,familyName):
print("{0} {1}".format(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(True,"小七","高")
printName(False,"Ivanka","Trump")
(二)nonlocal关键字
nonlocal 用来声明外层的局部变量
global 用来声明全局变量
#测试nonlocal/global关键字的用法
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)
(三)LEGB规则
python在查找“名称”时,是按照LEGB规则查找的
Local :指的几乎是函数或者类的方法内部
Enclosed:嵌套函数(一个函数包裹另一个函数,闭包)
Gobal:模块中的全局变量
Built in:指的是Python为自己保留的特殊名称
#测试LEGB规则
print(type(str))
#str = "global"
def outer():
#str = "outer"
def inner():
#str = "inner"
print(str)
inner()
outer()
二、面向对象编程
面向对象编程将数据和操作数据相关的方法封装到对象中,组织代码和数据方式更加接近人的思维,Python完全支持面向对象的基本功能,例如:继承、多态、封装等。
另:Python支持面向过程、面向对象、函数式编程等多种编程范式。
(一)面向对象和面向过程区别
面向过程编程关注“程序逻辑流程”是一种“执行者”思维,适合编写小程序:找动词
面向对象关注“软件中对象之间的关系”是一种“设计者”思维,适合编写大规模的程序:找名词
面向对象可以帮助我们从宏观上把握、从整体上分析整个系统,但是具体到实现部分的微观操作(一个个方法),仍然需要面向过程的思路去处理,遇到复杂问题,先从问题中找名词(面向过程更多的是找动词),然后确立这些名词哪些可以作为类,再根据问题需求确定类的属性和方法,确定类之间的关系。
(二)类的定义
通过类定义数据类型的属性(数据)和方法(行为),也就是说类将行为和状态打包在一起。
class Student: #类名一般首字母大写,多个单词采用驼峰原则
def __init__(self,name,score): #self必须位于第一个参数
self.name = name
self.score = score
def say_score(self): #self必须位于第一个参数
print("{0}的分数是:{1}".format(self.name,self.score))
s1 = Student("高齐",18)
s1.say_score()
(三)构造函数__init__()
1.扩展补充前面内容,一个python对象包含如下部分:
(1)id(identity识别码)
(2)type(对象类型)
(3)value(对象的值)
a.属性(attribute)
b.方法(method)
2.__init__()要点:
(1)名称固定,必须为__init__()
(2)第一个参数固定,必须为:self。指的是刚刚创建好的实例对象
(3)构造函数通常用来初始化实例对象的实例属性
(4)通过“类名(参数列表)“来调用构造函数。调用后,将创建好的对象返回给相应的变量。
(5)__init__()方法:初始化创建好的对象,初始化指的是:”给实例属性赋值“
(6)__new__():用于创建对象,但我们一般无需重定义该方法
(7)如果我们不定义__init__(),系统会提供一个默认的__init__方法,如果我们定义了带参的__init__方法,系统不用创建默认的__init__方法。
(四)实例属性和实例方法
1.实例属性从属于:实例对象的属性,也成为”实例变量“:
(1)实例属性一般在__init__()方法中通过如下代码定义:
self.实例属性名 = 初始值
(2)在本类的其他实例方法中,也是通过self进行访问:
self.实例属性名
(3)创建实例对象后,通过实例对象访问:
obj01 = 类名() #创建对象,调用__init__()初始xie
obj01.实例属性名 = 值 #可以给已有属性赋值,也可以新加属性
2.实例方法从属于实例对象的方法,格式如下:
def 方法名(self [,形参列表]):
函数体
方法调用的格式如下:
对象.方法名([实参列表])
要点:
(1)定义实例方法时,第一个参数必须为self。和前面一样,self指当前的实例对象
(2)调用实例方法时,不需要也不能给self传参,self由解释器自动传参
3.函数和方法的区别
(1)都是用来完成一个功能的语句块,本质一样
(2)方法调用时,通过对象来调用。方法从属于特定实例对象,普通函数没有这个特点
(3)直观上看,方法定义时需要传参,函数不需要
4.实例对象的方法调用本质:
s2 = Student("高希希",100)
s2.say_score()
Student.say_score(s2)
5.其他操作
(1)dir(obj)可以获得对象的所有属性、方法
(2)obj.__dict__ 对象的属性字典
(3)pass 空语句
(4)isinstance(对象,类型) 判断“对象”是不是“指定类型”
(五)类对象、类属性、类方法、静态方法
1.类对象
class Student: #类名一般首字母大写,多个单词采用驼峰原则
def __init__(self,name,score): #self必须位于第一个参数
self.name = name
self.score = score
def say_score(self): #self必须位于第一个参数
print("{0}的分数是:{1}".format(self.name,self.score))
stu2 = Student
s1 = Student("高淇",60)
s2 = stu2("高希希",100)
s1.say_score()
s2.say_score()
2.类属性
class Student:
company = 'SXT' #类属性
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.name,"的分数是:",self.score)
s1 = Student("张三",80) #s1是实例对象,自动调用__init__()方法
s1.say_score()
print("一共创建{0}个Student对象".format(Student.count))
✳内存分析实例对象和类对象创建过程✳
3.类方法
#测试类方法
class Student:
company = "SXT" #类属性
def __init__(self,name,age):
self.name = name
self.age = age
@classmethod
def printCompany(cls):
print(cls.company)
#print(self.name) #类方法和静态方法中,不能调用实例变量、实例方法
Student.printCompany()
类方法是从属于“类对象”的方法。
(1)@classmethod必须位于方法上面一行
(2)第一个cls必须有,cls指的就是“类对象”本身
(3)调用类方法格式:“类名.类方法名(参数列表)”。参数列表中,不需要也不能给cls传值
(4)类方法中访问实例属性和实例方法会导致错误
(5)子类继承父类方法时,传入cls是子类对象,而非父类对象
4.静态方法
Python中允许定义与“类对象”无关的方法,成为“静态方法”。静态方法和在模块中定义的普通函数没有区别,只不过放到了“类的名字空间里面”,需要通过“类调用”。
#静态方法使用测试
class Student2:
conpany = "SXT" #类属性
@staticmethod
def add(a,b): #静态方法
print("{0}+{1}={2}".format(a,b,(a+b)))
return a+b
Student2.add(20,30)
(六)__del__方法(析构函数)和垃圾回收机制
__del__:用于实现对象被销毁时所需的操作:比如释放对象占用的资源
#析构函数
class Person:
def __del__(self):
print("销毁对象{0}".format(self))
p1 = Person()
p2 = Person()
del p2
print("程序结束")
(七)__call__方法和可调用对象
#测试可调用方法__call__()
class SalaryAccount:
'''工资计算类'''
def __call__(self, salary):
print("算工资啦……")
yearSalary = salary*12
daySalary = salary//27.5 #国家规定的每个月的平均工资天数
hourSalary = daySalary//8
return dict(yearSalary=yearSalary,monthSalary=salary,daySalary=daySalary,hourSalary=hourSalary)
s = SalaryAccount()
print(s(30000))