Python学习笔记(九):类和对象

Python学习笔记(九):类和对象

一.类和对象

类(class)和对象(object,也被称为实例,instance),可以把类理解成某种概念,对象是一个具体存在的实体

类的定义

class 类名:
    执行语句...
    类变量...
    方法...

Python语法要求:类名只要是一个合法的标识符
从可读性看,Python的类名必须是由一个或多个有意义的单词连缀而成,每个单词首字母大写,其他字母全部小写,单词与单词间不使用分隔符

类的定义由类头(class关键字和类名)和统一缩进的类体构成

在类体中最主要的是类变量和方法
不为类定义任何类变量和方法,那么这个类就相当于一个空类
如果空类不需要其他可执行语句,可使用pass语句作为占位符

class YOU:
    pass  #空类没有太大的实际意义
类变量和方法的定义顺序没有任何影响,之间可以相互调用

类变量属于类本身,用于定义该类本身所包含的状态数据;实例变量属于该类的对象,用于定义对象所包含的状态数据

方法用于定义该类的对象的行为或功能实现

类所包含的类变量可以动态增加或删除,实例变量也可以动态增加或删除(del 语句)
方法的定义默认是实例方法,定义实例方法与定义函数基本相同

实例方法的第一个参数会被绑定到方法的调用者(该类的实例),实例方法至少应该定义一个参数,该参数通常被命名为self

实例方法中的__init__被称为构造方法

用于构造该类的对象,通过调用构造方法返回该类的对象(无须使用__new__)

如果没有为该类定义任何构造方法,那么会自动为该类定义一个只包含一个 self 参数的默认的构造方法
class test :
    '这是类定义的说明文档'  #为类定义说明文档
    name = 'you'     # 定义了一个类变量
    def __init__(self, Name = 'chanwill', age=20):  #使用构造方法
        self.Name = Name    # 为test对象增加的实例变量
        self.age = age
T = test()
print(T.Name)
chanwill

Python类的作用:定义变量,创建对象,派生子类

类定义说明文档,放在类声明之后、类体之前

类的实例化

创建类对象的过程,称为类的实例化

已定义好的类的类名(参数)

如果没有手动添加 __init__()构造方法,或者添加的 __init__() 中仅有一个 self 参数,则创建类对象时的参数可以省略不写
class test :
    name = "you"    #定义类变量
    age = "20"
    def __init__(self,name,age):
        self.name = name        #定义实例变量
        self.age = age
        print(name,"年纪为:",age)

    def say(self, content):     #定义实例方法
        print(content)

TEST = test("chanwill","21") #将test对象赋给TEST变量
chanwill 年纪为: 21

在上面的程序中,除self参数外,还包含2个参数且没有设置默认参数,因此在实例化类对象时,需要传入相应的值(self参数不需要手动传值)
在各个类方法之外(包含在类中)的变量为类变量(或者类属性),定义在类方法中的变量为实例变量(或者实例属性)

类对象的使用

  • 访问或修改类对象具有的实例变量,添加新的实例变量或者删除已有的实例变量
  • 调用类对象的方法,包括调用现有的方法和给类对象动态添加方法
类对象访问变量或方法

类对象名.变量名

对象名.方法名(参数)

对象名和变量名以及方法名之间用点 "." 连接
class test :
    name = "you"    #定义类变量
    age = "20"
    def __init__(self,name,age):
        self.name = name        #定义实例变量
        self.age = age
        print(name,"年纪为:",age)
    def say(self, content):     #定义实例方法
        print(content)
        
test.say("调用test的say()方法")
print(test.name,test.age)
test.name = 'youchanwill'       #修改实例变量的值
test.age = '20'
print(test.name,test.age)
you 20
youchanwill 20
给类对象动态添加/删除变量

test.money= 1016
print(test.money)

通过直接增加一个新的实例变量并为其赋值,成功地为对象添加了新的变量

del test.money
print(test.money)
AttributeError: money

使用 del 语句实现动态删除
给类对象动态添加方法

类对象动态添加方法,不会将调用者自动绑定到第一个参数(第一个参数命名为 self也没用)

def info(self): # 定义函数
    print("---info函数---", self)
test.foo = info # 使用info对test的foo方法赋值
test.foo(test)  # 不会自动将调用者绑定到第一个参数,需要手动调用

test.bar = lambda self: print('--lambda表达式--', self)# 使用lambda表达式为对象的方法赋值
test.bar(test) 
借助 types 模块下的 MethodType 可以实现不用手动给 self 传值

from types import MethodType
test.info = MethodType(info, test)

二.self用法

在定义类的过程中,无论是创建类的构造方法,还是向类中添加实例方法,都要求将 self 参数作为方法的第一个参数

类可以有很多类对象,都有相同的类变量和类方法,通过self参数,使每个类对象只能调用自己的类变量和类方法

同一个类可以产生多个对象,当某个对象调用类方法时,该对象会把自身的引用作为第一个参数自动传给该方法
Python会自动绑定类方法的第一个参数指向调用该方法的对象

class Person:
    def __init__(self):
        print("正在执行构造方法")

    def study(self):     # 定义一个study()实例方法
        print(self,"Python")
a = Person()
a.study()
b = Person()
b.study()
正在执行构造方法
<__main__.Person object at 0x02A3CE70> Python
正在执行构造方法
<__main__.Person object at 0x02A0A6F0> Python

study()中的self代表该方法的调用者,谁调用该方法,self就代表谁
class Person:
    name = "you"
    def __init__(self,name):
        self.name=name
a = Person("youchanwill")
print(a.name)
b = Person("b")
print(b.name)
youchanwill
b

对于构造函数中的self参数,其代表的是当前正在初始化的类对象

a在进行初始化时,调用的构造函数中 self 代表的是youchanwill;而b在进行初始化时,调用的构造函数中self代表的是b
class Person:
    def who(self):
        print(self)
you = Person()

you.who() #第一种方式

who = you.who #第二种方式
who()   #通过 who 变量调用you对象中的 who() 方法
<__main__.Person object at 0x0257A670>
<__main__.Person object at 0x0257A670>

无论采用哪种方法,self 所表示的都是实际调用该方法的对象
无论是类中的构造函数还是普通的类方法,谁实际调用它们,则第一个参数 self就代表谁

三.类方法

类方法具体可分为类方法、实例方法和静态方法

用 @classmethod 修饰的方法为类方法;用 @staticmethod 修饰的方法为静态方法;不用任何修改的方法为实例方法

实例方法

class test:
    def __init__(self):   #类构造方法,属于实例方法
        self.name = "you"
        self.age = "20"
    def say(self):     #定义一个say实例方法
        print("正在调用 say() 实例方法")

实例方法最大的特点是最少也要包含一个self参数,用于绑定调用此方法的实例对象

a = test()
a.say()

实例方法通常用类对象直接调用

a = test()
test.say(a)

用类名调用实例方法,需要手动给self参数传值

类方法

类方法和实例方法相似,最少也要包含一个参数,类方法中通常将其命名为cls,在调用类方法时,无需显式为 cls 参数传参

class test:
    def __init__(self):   #类构造方法,属于实例方法
        self.name = "you"
        self.age = "20"
    @classmethod
    def info(cls):
        print("正在调用类方法",cls)

类方法需要使用@classmethod修饰,如果没有 @classmethod,解释器会认定为实例方法,而不是类方法

类方法推荐使用类名直接调用,也可以使用实例对象来调用

静态方法

静态方法就是函数,和函数唯一的区别是静态方法定义在类命名空间,函数定义在全局命名空间

静态方法没有类似self、cls这样的特殊参数,解释器不会对它包含的参数做任何类或对象的绑定,类的静态方法中无法调用任何类属性和类方法

class test:
    @staticmethod
    def info(name,age):
        print(name,age)
        
静态方法需要使用@staticmethod修饰

test.info("you","20")#使用类名直接调用静态方法

a = test() #使用类对象调用静态方法
a.info("you","20")

静态方法的调用,既可以使用类名,也可以使用类对象

在实际编程中,几乎不会用到类方法和静态方法,可以使用函数代替它们的功能

静态方法和类方法的区别

类方法的第一个参数(cls)会自动绑定到类本身;静态方法则不会自动绑定

使用@classmethod 修饰的方法就是类方法;使用@staticmethod 修饰的方法就是静态方法

四.类命名空间

Python 中,编写的整个程序默认处于全局命名空间内,类体处于类命名空间内

class item:
    print('正在定义item类')    #在类空间中放置执行性质代码
    for i in range(5):
        if i % 2 == 0 :
            print('偶数:', i)
        else:
            print('奇数:', i)
正在定义item类
偶数: 0
奇数: 1
偶数: 2
奇数: 3
偶数: 4

在类体中放置普通的输出语句、循环语句、分支语句都是合法的
程序并没有定义变量或函数,可执行代码放在类命名空间与全局空间并无太大的区别
global_lambda = lambda p: print('执行lambda表达式', p)
class Category:
    cate_lambda = lambda p: print('执行lambda表达式 ', p)

global_lambda('you')  #调用全局范围内的global_lambda,为参数p传入值

c = Category() # 调用类命名空间内的cate_lambda,自动绑定第一个参数
c.cate_lambda()  

执行lambda表达式 you
执行lambda表达式  <__main__.Category object at 0x029F4F90>

全局空间定义的lambda表达式相当于普通函数,用调用函数的方式来调用该 lambda表达式,为第一个参数绑定参数值

类命名空间定义的lambda表达式相当于在类命名空间中定义了一个函数,这个函数就变成了实例方法

程序必须用调用方法的方式来调用该lambda表达式,为第一个参数(self 参数)绑定参数值
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值