目录

 

目录

一、函数用法和底层分析

(一)嵌套函数(内部函数)

(二)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支持面向过程、面向对象、函数式编程等多种编程范式。

(一)面向对象和面向过程区别

面向过程编程关注“程序逻辑流程”是一种“执行者”思维,适合编写小程序:找动词

面向对象关注“软件中对象之间的关系”是一种“设计者”思维,适合编写大规模的程序:找名词

面向对象可以帮助我们从宏观上把握、从整体上分析整个系统,但是具体到实现部分的微观操作(一个个方法),仍然需要面向过程的思路去处理,遇到复杂问题,先从问题中找名词(面向过程更多的是找动词),然后确立这些名词哪些可以作为类,再根据问题需求确定类的属性和方法,确定类之间的关系。

(二)类的定义

通过类定义数据类型的属性(数据)和方法(行为),也就是说类将行为和状态打包在一起。

python14%5 python145讲解_类方法

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))

✳内存分析实例对象和类对象创建过程✳

python14%5 python145讲解_python14%5_02

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是子类对象,而非父类对象

python14%5 python145讲解_静态方法_03

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))