python学习笔记(六)——类的初始化(__init__)、类属性和类方法 和 对象

学习本篇文章后会了解到:类的创建,为对象添加属性,对象的初始化,自定义对象的输出,类属性和类方法的创建。

1. 类的定义与格式

  • 类是对一群具有相同特征或者行为的事物的一个统称。

  • 类是一个模块,是负责创建对象的。

  • 类的命名采用大驼峰命名法。

  • 类中的特征称为属性,行为称为方法
    格式:

      class 类名:
      		def 方法1(self,参数列表):
      			pass
      		def 方法2(self,参数列表):
    

注意:在类中定义的方法中的第一个参数是self。当然也可以采用其他的名称只是习惯性的使用self。
要设计一个类,通常需要满足一下三个要素:

  1. 类名 这类事情的名字,满足大驼峰命名法。
  2. 属性 表示类具有什么样的特征。
  3. 方法 表示类具有什么样的行为。

1.1 创建类及self的含义

在类中创建一个函数时,系统自动在函数中添加self参数。哪一个对象调用的方法,self就是哪一个对象的引用;在调用方法时,不需要传递self参数。在方法内部调用对象的属性可以使用 self. 的方式,也可以通过 self. 调用其他的对象方法。

class Person:
    def run(self):
        print("跑步功能")
    def eat(self):
        print("吃饭")

# 创建两个Person对象,并分别调用类中的两个方法
tom = Person() 
tom.eat()
tom.run()
print()
danni = Person()
danni.run()
danni.eat()
print(danni)  #  打印出引用的地址
	
运行结果如下:
吃饭
跑步功能

跑步功能
吃饭
<__main__.Person object at 0x0000000002588C88>

补充:
在计算机中通常使用十六进制表示内存地址。
%d:可以以10进制输出数字
%x :可以以16进制输出数字

2. 对象

是由类创建出来的一个具体存在,可以直接使用如下的格式

	对象变量名 = 类名()

其实在面向对象过程中:变量,数据,函数都是对象

类和对象的关系
  • 类只有一个,而对象可以有很多个(类可以创建多个对象)。
  • 不同的对象之间属性可能会各不相同。
  • 类中定义什么属性和方法,对象中就有什么属性和方法,不可能多,也不能少

2.1. 给对象增加属性

方法一:
使用在类外界使用对象名 .属性名 ,利用赋值语句进行增加。

class Person:
    def run(self):
        print("%s跑步功能" % self.name )   # 格式化输出,在方法内部调用对象的属性,**self.**属性名
    def eat(self):
        print("吃饭")
	
tom = Person()  # 创建一个Person对象
tom.name = "Tom"  # 给对象添加一个属性 name
tom.run()
tom.eat()
print()

运行结果:
Tom跑步功能
吃饭

方法二:
下面讲到__init__()函数的时候会讲到

注意:

  • 在类的外部,通过变量名. 访问对象的属性和方法
  • 在类封装的方法中,通过self. 访问对象的属性和方法。

3. 初始化方法

当使用类名()创建对象时,会自动执行一下操作:

  1. 为对象在内存中分配空间—创建对象(__new__)
  2. 为对象的属性设置初始值—初始化方法(__init__

注意:以两个下划线开头以两个下划线结尾的函数为Python中的内置函数。可以直接被调用

3.1 __init__

__init__()方法是专门用来定义一个类具有哪些属性的方法,就是无论系统是否调用,都会被执行。
示例代码:

演示一:
class Cat:
    def __init__(self):
        print("这是初始化方法")	 # 系统会直接调用
cat = Cat()
演示结果:
这是初始化方法

演示二:添加属性并赋值
class Cat:
    def __init__(self):
        print("这是初始化方法")
        # self.属性名 = 属性的初始值
        self.name = "Tom"
    def eat(self):
        print("%s爱吃鱼" % self.name)
	
cat = Cat()
cat.eat()

结果:
这是初始化方法
Tom爱吃鱼

初始化的同时设置初始值:

  1. 把希望设置的属性值,定义成__init__方法的参数
  2. 在方法内部使用self.属性 = 形参 接收外部传递的参数。
  3. 在创建对象时,使用类名(属性1,属性2)调用

示例代码:

class Cat:
    def __init__(self,new_name):
        print("这是初始化方法")
        # self.属性名 = 属性的初始值
        self.name = new_name
    def eat(self):
        print("%s爱吃鱼" % self.name)

cat = Cat("Tom")
cat.eat()

结果:
这是初始化方法
Tom爱吃鱼

3.2 __del__()

__del__()方法,对象被从内存中销毁前,会被自动调用
示例代码:

class Cat:
   def __init__(self,new_name):
        print("这是初始化方法")
        # self.属性名 = 属性的初始值
        self.name = new_name
    def eat(self):
        print("%s爱吃鱼" % self.name)
    def __del__(self):
        print("%s走了"%self.name)  # 系统会自动调用
cat = Cat("Tom")
cat.eat()

结果为:
这是初始化方法
Tom爱吃鱼
Tom走了

3.3 __str__()

__str__方法,返回对象的描述信息,在方法内部必须返回一个字符串,使用return关键字,使用**print(对象名)**输出,自定义的内容,即return后面的字符串。
希望在程序中输出对象定义的内容,而不是输出内存地址。
示例代码:

class Cat:
    def __init__(self,new_name):
        print("这是初始化方法")
        # self.属性名 = 属性的初始值
        self.name = new_name
    def eat(self):
        print("%s爱吃鱼" % self.name)
    def __del__(self):
        print("%s走了"%self.name)
    def __str__(self):
        return "我是Cat%s"%self.name
cat = Cat("Tom")
print(cat)
print("*"*30)

结果为:	
这是初始化方法
我是CatTom
******************************
Tom走了

代码解释:
如果不加入__str__(self):

def __str__(self):
   	return "我是Cat%s"%self.name

当调用print(cat)时会输出:

<__main__.Cat object at 0x0000000001F18D30>

4. 实例

  1. 类创建出来的对象叫做类的实例
  2. 创建对象的动作叫做实例化
  3. 对象的属性叫做实例属性
  4. 对象调用的方法叫做实例化方法

在程序执行时:
1.对象各自拥有自己的实例属性
2.调用对象方法,可以通过self.

每一个对象都有自己独立的内存空间,保存各自不同的属性。多个对象的方法,在内存中只有一份,在调用方法时,需要把对象的引用传递到方法的内部。


以上所描述的都属于对象中的内容
Python属于面向对象的语言,一切皆对象

5. 类是一个特殊的对象

在类中包括也包括属性和方法,称:

  • 类属性
    • 类属性就是给类对象定义的属性,通常用来记录与这个类相关的特征,类属性不会用于记录具体对象的特征。
  • 类方法
    • 类方法就是针对类对象定义的方法

5.1 类属性

示例一:添加一个类属性,在实例化方法中调用类属性: 类名.类属性
class Tool(object):
    count = 0
    def __init__(self,name):
        self.name = name
        #让类的属性加 1
        Tool.count += 1
# 1.创建工具对象
tool = Tool("斧头")
tool1 = Tool("榔头")
print("工具的总数:%d"% tool1.count)
print(Tool.count)

结果:
工具的总数:2
2
调用类属性的方法
  • 类名.类属性

  • 对象名.类属性(不推荐使用),因为在Python中存在一个向上查找的机制,如果对象中没有count属性,则向上查找类属性。
    注意:
    如果使用对象.类属性 = 值 赋值语句,只会给对象添加一个属性,而不会影响到类属性的值。

      class Tool(object):
          count = 0
          def __init__(self,name):
              self.name = name
              #让类的属性加 1
              Tool.count += 1
      # 1.创建工具对象
      tool = Tool("斧头")
      tool1 = Tool("榔头")
      tool1.count = 100
      print("工具对象的总数:%d"% tool1.count)
      print("类属性%d"% Tool.count)
      结果:
      工具对象的总数:100
      类属性2
    

5.2 类方法

语法:

@classmethod
def 类方法名(cls):
	pass

描述:类方法需要用修饰器@classmethod来标识,告诉解释器这是一个类方法。
类方法的第一个参数应该是 cls

  1. 由哪一个类调用的方法,方法内的cls就是哪一个类的引用。

  2. 和实例方法中的第一个参数self类似。

  3. 使用其他名称也可以,不过习惯使用cls

  4. 通过类名.调用类方法,不需要传递cls参数。

  5. 在方法内部通过cls.访问类的属性。也可以通过cls.调用其他的类的方法

     class Tool(object):
     	# 使用赋值语句定义类属性,记录所有工具对象的数量
     	count = 0
     	# 定义一个类方法
         @classmethod
         def show_count(cls):
             print("工具对象的数量%d" % cls.count)
     
         def __init__(self,name):
             self.name = name
             Tool.count += 1
    
     # 创建工具对象
     tool1 = Tool("斧头")
     tool2 = Tool("榔头")
     # 调用类方法
     Tool.show_count()
     结果:
     工具对象的数量2
    

5.2.1 静态方法

既不需要访问实例属性或者调用实例方法,也不需要访问类属性或者调用类方法
不需要指定第一个参数。静态方法直接使用类名调用。
语法:

	@staticmethod
	def 静态方法名():
		pass

示例一:

class Dog(object):
    @staticmethod
    def run():
        print("小狗正在跑")
#通过类名.来调用静态方法,不需要创建对象
Dog.run()

结果:
小狗正在跑

示例二:

class Game(object):
    # 定义一个类属性——历史最高分
    top_score = 0
    def __init__(self,play_name):
        self.play_name = play_name
        
    @staticmethod
    def show_help():
        print("帮助信息")
        
    @classmethod
    def show_top_score(cls):
        print("历史记录%d:" %cls.top_score)

    def start_game(self):
        print("%s开始了"%self.play_name)

# 1.查看游戏的帮助信息
Game.show_help()
# 2.查看历史最高分
Game.show_top_score()
# 3.创建游戏对象
game = Game("小曾")
game.start_game()

结果:
帮助信息
历史记录0
小曾开始了

总结:
1.实例方法——方法内部需要访问实例属性
- 实例方法内部可以使用类名.访问类属性
2.类方法——方法内部只需要访问类属性
3.静态方法——方法内部,不需要访问实例属性和类属性
问题:
如果方法内部即需要访问实例属性,又需要访问类属性,应该定义成什么方法?

  • 应该定义成实例方法
  • 类只有一个,在实例方法内部可以使用类名.方法类属性。
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章