11.8 学习日志

(十)nonlocal和global关键字

nonlocal用来在内部函数中声明外层的局部变量,然后再使用

global是在函数内声明全局变量,然后再使用

(十一)LEGB规则

发生变量名字冲突时,按照LEGB规则来找

Local:函数或者类的内部

Enclosed:嵌套函数

Global:模块中全局变量

Built in:Python为自己保留的特殊名称

29 对象和类

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

面向对象:“设计者思维”,首先思考怎么设计,将复杂事物分解,需要很多协作完成,具体到实现部分的微观操作,仍然需要面向过程去处理

面向过程:“执行者思维”,适合简单事物,关注如何执行

(二)类

类是图纸,根据图纸造出对象

属性(变量)是状态,方法(函数)是行为,把具有相同属性和方法的对象归为一类

从一个类创建对象时,每个对象会共享这个类的方法,但会有自己的属性值

class 类名:
    类体

1.类名必须符合“标识符”规则,一般规定首字母大写,多个单词使用“驼峰原则”

2.类体中可以定义属性和方法

3.属性用来描述数据,方法(函数)用来描述数据相关的操作

class Student:

    def __init__(self,name,score):     #定义构造方法,局部变量变成类的属性,在其他方法里也可以使用
        self.name = name        #name和score本身是局部变量,在这里处理完后就变成了属性
        self.score = score

    def say_score(self):
        print("{0}的分数是{1}".format(self.name,self.score))

s1 = Student("zhangsan",80)     #s1对象实际调用的是构造方法
print(s1.name,s1.score)
s1.say_score()

#zhangsan 80
#zhangsan的分数是80
(三)__init__构造方法

1.名称固定,必须为__init__()

2.第一个参数固定,必须为self。self指的是刚刚创建好的实例对象

3.通过“类名”来调用构造函数,调用后,将创建好的对象返回给相应的变量

4.__init__()方法:初始化创建好的对象,初始化指的是:“给实例属性赋值”

   __new__()方法:用于创建对象,但一般无需重定义该方法

如果不定义带参的__init__(),系统会提供一个默认的无参的

(四)实例属性

实例属性是从属于实例对象的属性,也叫“实例变量”

1.实例属性一般在__init__()中,通过如下定义:

self.实例属性名=初始值

2.在本类其他实例方法中,也是通过self进行访问:

3.创建实例对象后通过实例对象访问:

obj01=类名()

obj01实例属性名=值#给已有属性赋值,也可以新加属性

如果在创建的某个实例对象下新增属性,则该属性只在该实例对象内,其他实例对象无法调用

新增属性一般都放在构造函数里,比较整齐

(五)实例方法
def 方法名(self,形参)
    函数体

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

定义实例方法,第一个参数也必须为self,调用实例方法不能给self传参

class Student:

    def __init__(self,name,score):     #定义构造方法,局部变量变成类的属性,在其他方法里也可以使用
        self.name = name        #name和score本身是局部变量,在这里处理完后就变成了属性
        self.score = score

    def say_score(self):
        print("{0}的分数是{1}".format(self.name,self.score))

a = Student("zhangsan",80)
a = Student()
a.say_score(68)
#实例对象的方法调用本质是Student.say_score(a,68)
print(dir(a))       #返回a这个对象的所有属性和方法
print(a.__dict__)       #返回a这个对象的所有属性
print(isinstance(a,Student))        #判断a是不是Student这个类的实例对象
(六)类对象

在定义类时,执行class语句,就是在生成一个类对象

对象类型就是type

class Student:
    pass

Stu = Student       #Stu和s都指向了同一个类对象Student
s = Stu()
print(s)
(七)类属性

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

class Student:
    count = 0       #类属性

    def __init__(self,name,score):
        self.name = name        #实例属性
        self.score = score
        Student.count = Student.count + 1       #统计有多少个学生,因为每一次都会调用构造函数

    def say_score(self):       #实例方法
        print(self.name,'的分数是:',self.score)

s1 = Student("zhangsan",80)     #s1是实例对象
s2 = Student("lisi",70)
s1.say_score()
print("一共创建{0}个Student对象".format(Student.count))

#zhangsan 的分数是: 80
#一共创建2个Student对象
(八)类方法

类方法是从属于“类对象”的方法

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

第一个cls必须有,cls指的是“类对象”本身

类方法中不能调用实例属性,实例方法

(九)静态方法

静态方法在模块中定义普通函数没有区别,只是“静态方法”放到了“类的名字空间里”,需要通过“类调用”

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

静态方法中也不能访问实例属性和实例方法

(十)__del__方法(析构函数)

当对象没有被引用时,由垃圾回收器调用__del__()

__del__()用于实现对象被销毁时所需的操作

class Student:
    count = 0       #类属性

    def __init__(self,name,score):
        self.name = name        #实例属性
        self.score = score
        Student.count = Student.count + 1       #统计有多少个学生,因为每一次都会调用构造函数

    def __del__(self):
        print("qingchu")
    def say_score(self):       #实例方法
        print(self.name,'的分数是:',self.score)

s1 = Student("zhangsan",80)     #s1是实例对象
s2 = Student("lisi",70)
s1.say_score()
#s2.say_score()
del s2
print("一共创建{0}个Student对象".format(Student.count))

'''zhangsan 的分数是: 80
qingchu
一共创建2个Student对象
qingchu
'''

???

 (十一)__call__方法和可调用对象

在调用函数时,本质上就使用了__call__()

class Car:
    def __call__(self,age,money):
        print("call 方法")
        print("车龄{0},金额{1}".format(age,money))

c = Car()
c(3,200000)

#call 方法
#车龄3,金额200000
(十二)方法没有重载以及方法的动态性

定义多个重名的方法,只有最后一个有效

动态给类添加方法,动态修改类方法

class Person:
    def work(self):
        print("努力工作")

def play_game(s):       #s是必要的,如果没有s添加到类里再调用时会报错,相当于没有self,s是为了给self留位置,添加到类系统会将其自动转为self
    print("玩游戏")

def work2(s):
    print("好好工作")

Person.play = play_game     #给Person类里新加函数play
Person.work = work2     #将Person类里的work函数修改为work2

p = Person()
p.play()
p.work()

#玩游戏
#好好工作
(十三)私有属性和私有方法

Python对于类的成员没有严格的访问控制限制,只是约定:

1.双下划线开头是私有

2.类内部可以访问私有属性(方法)

3.类外部不能直接访问私有属性(方法)

4.类外部可以通过“_类名__私有属性名”访问私有属性

class Employee:
    __company = "lll"        #解释器运行时,把__company转成了_Employee__company

    def __init__(self,name,age):
        self.name = name
        self.__age = age
    def say_company(self):
        print("我的公司是:",Employee.__company)
        print("我的年龄是:",self.__age)          #内部调用的时候不用换名字

print(Employee._Employee__company)      #在外部调用的时候要换名字
a = Employee("lmh",18)
a.say_company()

#lll
#我的公司是: lll
#我的年龄是: 18
(十四)_@property装饰器

@property装饰器可以将一个方法的调用方式变成“属性调用”

@property主要用于帮助我们处理属性的读操作、写操作。对于某一个属性,我们可以直接通过: 

emp1.salary=30000

class Employee:

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

    @property
    def age1(self):
         print("我的年龄是:", self.__age)
         return self.__age

a = Employee(18)
print(a.age1)

#我的年龄是: 18
#18

看似调用的是属性,其实调用的是方法

(十五)属性和类的命名规则

_xxx:保护成员,不能用from module import*导入,只有类对象和子类对象能访问这些成员

_xxx_:系统定义的特殊成员e.g._init_()

_xxx:类中的私有成员,只有类对象自己能访问,子类对象也不能访问。(但在类外部可以通过对象名._类名_xxx这种方式访问)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值