python类(class)

类(class)

  • 到目前为止所学习的对象都是python内置的对象

  • 但是内置对象并不能满足所有的需求,所以我们在开发中需要自定义一些对象

  • 自定义一些对象就差不多是创建类,然后赋值给这个变量,这个变量就是这个类了

  • 类,简单理解就相当于一个图纸,在程序中我们需要根据类来创建一个对象

  • 对象就是类的实例化(instance)

  • 如果多个对象是通过一个类来创建的,我们称这些对象是一类对象

  • int() str() boor() float() list() tupe() dict() 等,这些都是类

  • 在定义类的时候需要使用大写字母开头,使用大驼峰命名法来对类命名

  • 类也是一个对象 ,类就是用来创建对象的对象

  • 类是type类型的对象,定义类实际上就是定义了一个type类型的对象

定义一个简单的类

  • 使用class关键字来定义类,语法和函数很像
  • 语法:
    class 类名([父类])
        代码块
    例:
    class Lmk():
    	pass
    # 这就是一个简单的类
    	
    # 用类创建一个对象
    ob = Lmk()
    print(ob)
    # 打印结果是 <__main__.Lmk object at 0x000001846F21D160> ob 是 Lmk这个类
    

isinstance() 函数

  • 格式
    isinstance(对象名,类名)

  • 这个函数是判断这个对象是不是这个类

    例:
    # ob是上面创建的类
    print(isinstance(ob,Lmk))
    # 输出结果是 True 说明是同一个类
    print(isinstance(ob,str)) 
    # 这个输出结果是 False,说明不是同一个类

使用类创建对象的流程

  • 定义类
  • 上面定义的是 Lmk 这个类
    class Lmk(): 
    	pass
    # 这个过程是 创建一个 type类型的 对象 名字是 Lmk ,然后存到内存中 		
    	# id= xo123
    	# type= <class type>
    	# value = None  
    # Lmk这个对象就指向 xo123这个id了 ,创建对象的图纸就有了
    
    ob = Lmk():
    # 这个过程是 创建Lmk类型的对象 名字是 ob 然后存到内存中
    	# id = xo223
    	# type = <class Lmk> 
    	# value = None
    # ob 这个对象就指向内存中的 xo223 ,一个Lmk类型的对象就创建好了
    # 然后调用这个对象就可以找到内存中对应的 value 因为没有赋值所以 valueNone

类的属性

  • 现在我们通过 Lmk这个类创建的对象是一个空对象
  • 也就是对象中实际上什么都没有,就相当于一个空的盒子
  • 可以向对象中添加变量,对象中的变量称为属性
  • 语法:
    对象.属性名 = 属性值
    例:
    # 这个是上面定义类
    class Lmk(): 
    	pass
    
    # 创建Lmk这个对象
    ob = Lmk()
    
    # 给Lmk对象创建属性并赋值
    ob.name = 'lmk'
    print(ob.name)
    # 输出结果是 lmk
    # 这时 内存中的value值就变化了
    					
    				# id = xo 223
    				# type = <class Lmk> 
    				# value : name = '李明凯'
    				# value的值由None 变为了 name = '李明凯'

类的方法

  • 在类中定义的函数,我们称为方法
  • 这些方法可以通过该类的所有实例来访问(也是公共的)
  • 语法

def 方法名():

  • 类似于定义函数
  • 下面类的定义中 有定义类的方法(函数) 和 类的属性(变量)

类的定义

  • 类和对象都是对显示生活中或程序中内容的抽象

  • 实际上所有的事物都由两部分组成(类的组成)
    1.数据(属性)
    2.行为(方法)

    在类的代码块中,我们可以定义变量和函数
    变量会成为该类实例的公共属性,所有的该类实例都可以通过 对象.属性名 的形式进行访问
    函数会成为该类实例的公共方法,所有的该类实例都可以通过 对象.方法名() 的形式调用方法

  • 注意:

    方法调用时第一个参数由解析器自动传递(就是调用方法是即使不传参数,也会默认传一个参数),所以定义方法是,至少定义一个形参

  • 下面定义一个简单的类

    # 定义一个简单的类 
    
    # 类的属性
    class Lmk():
                     # 在代码块中,我们可以定义变量和函数
                     # 在类中我们所定义的变量,将会成为所有实例的公共属性
                     # 所有实例都可以访问这些变量 
    	# name 就相当于类的属性 (公共的)
    	name = 'lmk'
    
    # 类的方法
    
    	# hello 就相当于类的方法 (公共的)
    	def hello(self):
    		print('hello')
    	# 定义方法是至少要定义一个形参,因为对象在调用方法时,解释器会默认传入一个参数,这个参数是我们刚才创建的对象,
    	# 谁调用这方法这个对象就是谁 这个self就是调用者
    
    kk = Lmk()    # 这是定义了一个 Lmk()这个类的对象 名字为 kk
    print(kk.name)        # 调用Lmk这个类的属性name并打印出来
    kk.hello()		# 调用Lmk这个类的hello方法
    # 输出结果	
    	# 李明凯
    	# hello
  • 调用方法和调用函数的区别

    如果是函数调用 ,则调用是传入几个参数,就会有几个实参
    如果是方法调用,则会在调用时默认传入一个参数,所以方法中至少要定义一个形参(self)

上面类定义的一些疑惑

  • 这里kk这个对象可以访问类的属性,那为什么可以访问呢

    • 因为类中定义的属性和方法都是公共的,任何该类实例都可以访问
  • 说一下kk是怎么找到name这个属性的

  • 属性和方法查找过程

    • 当我们调用一个对象属性时,解析器会先在当前对象中寻找是否含有该属性
    • 如果有,就直接返回当前对象的属性值
    • 如果没有,就去当前对象的类对象中去寻找,如果有则返回类对象的属性值,没有则报错
    • 一般情况下属性保存到实例对象中,而方法需要保存到类对象中
      # 属性:
      # 接上面的定义
      kk.name ='kml'
      # 这时kk的name属性就是kml了 不是lmk了
      # 之前是lmk是因为kk里没有name这个属性,所以去类中寻找到name,然后返回
      # 方法
      # 方法就要定义在类中了,因为属性每个对象都是不一样的,而方法是根据这个类创建的,每个属性都
      # 有这个方法,所以要创建到类中
      class Lmk():
      	def hello(self):
          	print('hello')
      				
      kk.name = 'lmk'
      ll.name = 'kml'          
      # 两个对象分别定义了两个不同的属性
      # 现在我们要两个对象在调用方法时显示不同的效果
      #   def hello(self):
      #      print('hello')
      
      # 这个方法是输出 hello ,现在修改一下,谁调这个方法就 hello 就显示谁的名字
      	def hello(self):
              print('hello%s'%self.name)
      # 现在就可以了,这个self就是之前解释器默认传的参数,这参数就是对象本身
      # self.name就是 调用对象的属性
      # 在默认情况下方法内的参数是self都这样写的,虽然也可以是别的字母,但是都写self
    • 完整代码(上面的供理解,下面的是真正的)
      class Lmk():           # 定义一个 Lmk这个类
      	name = 'lmk'    # 定义一个公共属性 name
      	def hello(self):      # 定义一个公共方法 hello        self 是默认传入的参数,谁调用这个方法这个参数就是那个对象
      		print('hello%s'%self.name)        
      
      kk = Lmk()      # 用Lmk这个类创建一个类型是 Lmk这个类的 kk对象
      ll = Lmk()      # 用Lmk这个类创建一个类型是 Lmk这个类的 ll对象
      
      kk.name = 'kkk'   # 定义 kk这个对象的 name属性  不定义的话默认是 类中的name
      ll.name ='kml'    # 定义ll这个对象的 name属性 不定义的话默认是 类中的name
      
      kk.hello()     # kk这个对象调用 Lmk这个类的hello方法
      ll.hello()	   # ll这个对象调用Lmk这个类的hello方法
      
      # 输出结果
      		# hellokkk
      		# hellokml

类的特殊方法__init__

  • 上面定义类已经是有一个模型了,但是还是不够完美

  • 如果用上面的类去定义的话,我们每用类创建一个对象都需要手动定义一个类的属性,如果工作量大或者忘记定义就会不知道是哪里的bug

  • 目前来讲,对于类来说属性是必须的,并且每个对象中的name中的name属性基本上都是不同的

  • 而且我们现在是将属性在定义对象以后,手动添加的,这种方式很容易出现错误

我们希望的是在创建对象是,必须设置name的属性,如果不设置,对象就无法创建
并且属性的创建应该是自动完成的,而不是在创建对象后手动完成的

  • 这就用到了一个特殊方法,而且这个特殊方法是在创建类时必须使用的

    在类中可以定义一些特殊方法(魔术方法)
    特殊方法都是以__ 开头,__结尾的方法
    特殊方法不需要我们自己调用,不要尝试去调用特殊方法
    特殊方法将会在特殊时刻自动调用

  • 特殊方法:

    • 特殊方法是在用类创建对象是立刻调用的

    • 特殊方法__init__作用是初始化对象的属性

    • 既然是必须要创建的那么就要写一个完整的创建对象的流程了

      在用类创建对象时首先
      1,创建一个变量用来存放对象
      2,在内存中创建一个新对象
      3,(类中的属性先生效,在对象中生效,可以随便调用)
      4,__init__(self) 特殊方法执行
      5.将对象的内存id赋值给变量

    • init特殊方法会立即在对象创建后执行(下面会演示__init__方法的用法)

类的基本结构

  • 大致结构
    class 类名([父类]):
    	公共属性
    
    	# 初始化对象的方法			
    	def __init__(self,**):	
    		....
    	# 其他方法
    	def method(self):
    		....
    例:
    class lmk():
        
    	def __init__(self,name):           # (这一步是初始化对象的属性)
    		self.name = name           # (为对象属性赋值,对象的属性就可以在定义的时候就被创建了)
     
    	def kkml(self):                # (定义对象的方法)
    		print('hello%s'%self.name)      
    
    
    kk = lmk('李明凯')      # 用lmk类创建一个 lmk类的kk对象 并给这个对象的一个属性赋值(赋值通过传参进行的)
    ll = lmk('kml')       # 同理
    oo = lmk('kkk')       # 同理
    kk.kkml()      # 用对象调用这个类的方法(因为是公共的)
    	
    # 输出结果是 hello李明凯

本博客所有文章是以学习为目的,如果有不对的地方可以一起交流沟通共同学习 邮箱:1248287831@qq.com!