类方法,静态方法和实例方法

2020-12-02 16:45:14 浏览数 (1)

文章总览图

本文简介

  • 面向对象编程--类的创建
  • 面向对象编程--继承与初始化函数
  • 面向对象编程--类的封装与复用

类的语法

类是个抽象的概念:例如大佬类,小白类。类的划分标准:写代码的人来定。

例如:

my only 大佬类里面的一个具体大佬

monica 小白类里面一个具体的小白

Python 类的语法

1.关键字是class。写法结构是class 类名:

2.类名的规范是: 1 数字字母下划线组成 2 不能以数字开头 3 首字母大写,驼峰命名 (例如:TestResult

3.类属性。例如a=1 放在类里面的变量值。

4.类方法/类函数:就是写在类里面的函数。类函数/类方法:类函数就是类方法。函数以 def 开头。写法结构是def 函数名(参数):

5.类函数定义:写在类里面就是类函数。

代码语言:javascript复制
'''
男朋友类   女朋友类

理想的女朋友标准是什么?

长发 温柔 大长腿 学历 工作 3-5 测试经验 会自动化

理想的男朋友的标准是什么?

体贴 有钱 175 绅士 温柔 会做饭 会赚钱
'''

class BoyFriend:#男朋友的模板 BoyFriend 就是类名

 类属性:

 height=175

 weight=130

 money="500万"

 

 def print_msg(self):#self 是实例本身 self 是固定的占坑符号 类里面的方法都必须带 self 这个参数

   print(self) #这里 self 是实例本身,这里实例就是 BoyFriend()

 def cooking(self): #会做饭 self

   print(self)

   print("男朋友要会做饭!")

 def earn(self): #会挣钱

   print("男朋友月薪是 3 万!")

1.实例也就是对象。实例就是个具体的1个例子。类名() 例如:BoyFriend()

2.怎么去创建一个实例/对象?类名()

代码语言:javascript复制
bf=BoyFriend()

print(bf)

print("*"*20)

#print("*"*20)  #print 表示自动换行

bf.print_msg()  #调用方法/函数

print(bf.money) #调用属性

1.实例具有类里面的所有属性和方法的使用权限。

2.实例可以调用类里面的任意属性,实例可以调用类里面的任意函数/方法。

3.调用属性:实例名.属性名

4.调用方法/函数:实例名.方法名()

实例名.函数名

函数名和方法名是一个东西,叫法两种。

5.普通函数和类函数区别:类函数有个self

QA类

写一个软件测试工程师类,要求有属性有函数,并完成属性和函数的调用。

代码语言:javascript复制
class SoftwareQAEngineer:

 #类属性

 title='QA'

 age='20-35'

 experience='2-3年'

 salary='1.5w'

 #函数

 def test_function(self):#例如 test_function()本身的作用是输出后面的“我会功能测试”

 #print("我会功能测试")

   return("我会功能测试")

 def test_api(self):

   print("我会接口测试")

 def major(self):

   print("计算机科学与技术")

 def test_auto(self):

   print("我会自动化测试")

qa=SoftwareQAEngineer()

#属性调用

print("测试工程师的年龄是:",qa.age)

print("测试工程师的经验要求:",qa.experience)

print("测试工程师的薪资待遇:",qa.salary)

print(qa.title)

#函数调用

qa.major()

qa.test_api()

qa.test_auto()

qa.test_function()

'''
输出:

测试工程师的年龄是:20-35

测试工程师的经验要求:2-3年

测试工程师的薪资待遇:1.5w

QA

计算机科学与技术

我会接口测试

我会自动化测试

我会功能测试
'''

print(qa.test_function())

输出:#None

问题分析:

test_function()本身的作用是输出“我会功能测试”到这个控制台。print已经输出了,再次使用print(qa.test_function())进行输出,已经没有值可以输出了,所以输出None

printreturn的区别:

如果把print("我会功能测试")改为return("我会功能测试")

return是当你调用这个函数的时候,它会返回一个值,返回return。后面的这个值"我会功能测试",当我使用print(qa.test_function())的时候,会返回到控制台。

类与对象

1.类的概念:具有某一类共同属性和特性的事物。

2.类一般包含属性方法

3.类可以包含属性和方法。也可以不包含属性和方法。

代码语言:javascript复制
class Teacher:#不包含属性和方法

 pass
代码语言:javascript复制
class Teacher:

   name="小红"

   age="25"

 def coding(self):#函数里面第一个参数是self,就是实例方法。

   #print("会敲代码")

   print(self.name "会敲代码")

 def cooking(self):#函数里面第一个参数是self,就是实例方法。

  # print("会做蛋炒饭")

   print(self.name "会做蛋炒饭")

 @classmethod #类方法

 def swimming(cls):#cls 就是类本身。

   print("老师还要会游泳")

 @staticmethod#静态方法

 def sing():#不用传任何参数,就是个普通函数。

   print("要会唱歌")

t=Teacher()#实例,隐式的传递。

t.cooking()#隐式的传递。

Teacher.coding(t)#显示的传递,不建议使用。

Teacher.sing()#类名调用。

t.sing()#实例调用。

'''

输出:

会做蛋炒饭

会敲代码

要会唱歌

要会唱歌

老师还要会游泳

老师还要会游泳

'''
Teacher.swimming()

t.swimming()

1.Teacher.coding()

报错:TypeError: coding() missing 1 required positional argument: 'self'

提示:缺少一个位置参数self

Teacher.coding(self)

报错:NameError: name 'self' is not defined

2.self必须传的是实例本身,如果创建实例的话,它就会默认把这个实例传到self这个位置。

如果直接类名.coding()就会报错。把实例传进去,变为Teacher.coding(t)就可以了。

类中的3种方法

1.实例方法:

意味着这个方法只能实例来调用。

实例 Teacher()

Teacher

2.类方法:

@classmethod

调用类方法:Teacher.swimming()

t.swimming()

类方法的调用:不创建实例,创建实例,都可以调用。

3.静态方法:

@staticmethod

调用静态方法:Teacher.sing()

t.sing()

  • 总结:实例方法self,类方法cls,静态方法就是(普通方法)
  • 共同点:三种方法都可以通过实例和类名调用。
  • 不同点:类方法和静态方法,不可以调用类里面的属性值。如果你要参数,请自己传递参数。

1.什么时候去定义静态和类方法呢?

当你的某个函数与其它的函数没有任何关系的时候,就可以定义为静态方法和类方法。

静态方法和类方法只是为了方便调用,不需要创建实例,直接类名.函数名就可以完成调用。

代码语言:javascript复制
class AppleTeacher:

 def_init_(self,name,age=23):#初始化函数 这是个实例方法 初始化函数可以有默认值。一般不传动态参数和关键字参数。

#外面的属性值变成里面的,就加 self 赋值。此处关键字参数是 age=23。

   self.name=name

   self.age=age

   self.height=168

#初始化函数没有返回值,不要写 return。

# 错误写法:

# def _int_(self):#这个不是初始化函数。

# pass

 def love_singer(self,love_singer):

   return(self.name "喜欢的歌手是{0}".format(love_singer))

 def coding(self,lines,language="Python"):#函数里面第一个参数是 self 就是实例方法。

# 这里的 language 是形参。"Python"是默认参数。位置参数 lines 要放在默认参数之前。

   #print("会敲代码")

   print(self.name "会敲{0}代码,写了行{1}代码".format(language,lines))

 def cooking(self,*args):#函数里面第一个参数是 self 就是实例方法。

 #动态参数*args。

 for item in args:#动态参数包含 0 个或多个,不计数。

  # print("会做蛋炒饭")

   print(self.name "会做{0}".format(item))

 def teacher_info(self,*args):

   self.cooking(*args)

   print("{0}老师,今年{1}岁,身高{2},可以嫁人了!".format(self.name,self.age,self.height))

# @classmethod #类方法

# def swimming(cls):#cls 就是类本身,可在第一个参数 cls 后面加参数。

  # print("老师还要会游泳")

# @staticmethod#静态方法

# def sing(name):#不用传任何参数 就是个普通函数

  # print("要会唱{0}".format(name))

'''
初始化函数

1.错误写法:

t1=AppleTeacher()

TypeError: _init_() missing 2 required positional arguments: 'name' and 'age'

2.什么时候用初始化函数?

想用就用,不想用就不用。

规律:如果某个属性值是多个函数共用的,就可以用初始化函数。

'''

# t1=AppleTeacher("清菡","25")

# t2=AppleTeacher("毛毛")

# t1.coding(1000)#在这里给位置参数 lines 赋值,位置参数是没有默认值的

# t1.cooking('蛋炒饭','小炒肉','方便面')

# print(t1.love_singer("萧亚轩"))

# t1.sing("邓丽君的《你怎么说》")

# t2.teacher_info()

t3=AppleTeacher("星星")

t3.teacher_info("多宝鱼","鲈鱼")

# t2=AppleTeacher("张三","22")

# t3=AppleTeacher("李四","20")

# t4=AppleTeacher("王五","18")

# t1.swimming()

# t2.cooking()

# t3.coding()

# t4.sing()

总结:不管是类方法,静态方法和实例方法,它的函数和普通函数一模一样的, 无区别。类方法,静态方法和实例方法的参数传递和return这些无区别。

继承

代码语言:javascript复制
class RobotOne:#第一代机器人

 def _init_(self,name,year):

   self.year=year

   self.name=name

 def walking_on_ground(self):

   print(self.name "只能在平地行走,有障碍物就会摔倒。")

 def robo_info(self):

   print("{0}产生的机器人{1},是中国研发的".format(self.year,self.name))

#继承

# class RobotTwo(RobotOne):#第二代机器人继承于第一代机器人的类。

# def walking_on_ground(self):#子类里面的函数名与父类里面的函数名重复的时候就叫重写。

# print(self.name "可以在平地上平稳地行走")

#def walking_avoid_block(self):#继承下面,这个是拓展。

#我想在子类的一个函数里面,调用父类的一个函数。

# self.robo_info()

# print(self.name "可以避开障碍物")

#为了多继承写的第二代机器人

class RobotTwo():#第二代机器人继承于第一代机器人的类。

 def _init_(self,name):

   self.name=name

 def walking_on_ground(self):#子类里面的函数名与父类里面的函数名重复的时候就叫重写。

   print(self.name "可以在平地上平稳地行走")

 def walking_avoid_block(self):

   print(self.name "可以避开障碍物")

#第二代机器人

继承的类是否要用到初始化函数?请看是否从父类里面继承了。

1:父类有的,继承后,我都可以直接拿过来用。

2:父类有,子类也有重名的函数,那么子类的实例就优先调用子类的函数。

# r2=RobotTwo("1990","小王")

#r2.robo_info()

#r2.walking_on_ground()

# r2.walking_avoid_block()

# r1=RobotOne("1988","小明")

# r1.walking_on_ground()#父类只能调用自己的方法

知识点:多继承就是继承多个父类。

#第三代机器人

class RobotThree(RobotTwo,RobotOne):#第三代机器人继承于第一代和第二代机器人的类

#第一代机器人和第二代机器人之间不能有继承关系,不然就会报错,提示重复继承了

 def _init_(self,year,name):

   self.year=year

   self.name=name

 def jump(self):

   print(self.name "单膝跳跃")

r3=RobotThree("2001","大王")

r3.jump()

r3.walking_on_ground()

r3.walking_avoid_block()

r3.robo_info()

疑问:没有year参数,调用robot_year就会报错,怎么办?

没办法解决,自己写函数时注意,避免遇到这种情况。或者重写第三个机器人。

多继承的子类具有两个父类的属性和方法 如果两个父类具有同名方法的时候, 子类调用函数就近原则,初始化函数也包括在内。

封装是什么?

把属性和函数封装到一个类里面就是封装。PythonJava中叫法是不一样的。

1.复习点:

1.如果类里面有初始化函数,创建实例的时候,就必须要在实例里面传递对应个数的参数。

2.调用函数的时候,必须实例调用,多复习类函数,静态函数,实例函数。

2.拓展点:

实例存到变量里面去调用方法,还是直接创建实例调用方法?

例如:

方法 1:

User('helen','can','30',165','110').describe_user()

方法 2:

u1=User('helen','can','30',165','110')

u1.describe_user()

创建多个实例会造成内存的浪费,不知道什么时候回收。如果不需要调用别的方法,就用第一种。

如果这个实例在别的地方也需要用到,建议把实例创建后存到一个变量里面,方便随时使用。两种方法实现的效果一样。

3.补充:

grade={"**语文":118,"数学":88,"英语"**:122}

可使用高阶函数 sorted


0 人点赞