一、定义类:
在Python中,定义类通过class
关键字:
class 类的名称:
# 类中的内容 描述属性和技能
#描述属性用变量
#描述行为用函数
#类名称 书写规范 首先是见名知意 名称是大驼峰命名法
#驼峰就是单词首字母大写 , 大驼峰是第一个字母大写,小驼峰是第一个字母小写
class后面紧跟的类名:类名通常是大写开头的单词,多个单词时使用‘驼峰命名法’
二、创建对象
创建对象也称之为实例化,定义好Student
类后通过类名加上()实现:
class Person:
name=123#变量描述属性
#创建对象
p = Person()
#
print(p)
#<__main__.Person object at 0x0000000001E2F9E8>
#main模块下的对象
print(Person)
#<class '__main__.Person'>
#类,mian下的person类
三、对象的属性操作
对象是特征(属性)与行为(方法)的结合体
3.1、为对象添加属性方法(在创建对象后使用点语法):
stu1
这个对象目前不具备任属性和方法,要为其添加属性可以在创建对象后使用点语法(变量名加 . )
比如为stu
对象添加name属性
stu1=Student()
stu1.name='wx'
3.2写在了类中:
class Person
name='wx'
3.3、获取对象属性方法:
还是通过点语法获取属性
print(stu1.name)
总结:
属性可以写在类中
类中的属性,是所有对象公共的
class Person:
name='张三丰'
p1 = Person()
print(p1.name)#张三分
p2 = Person()
print(p2.name)#张三分
也可以写在对象中
对象中的属性,是每个对象独特的(不一样的)
p3 = Person()
p3.name = "李四"
print(p3.name)
#李四
如果类中和对象中存在同样的属性,先访问对象 如果没有在访问类
p = Person()
p.name = "李四"
print(p.name)#李四
4、练习:描述一个老师类 需要包含 一个公共属性和 一个独特的属性
class Teacher:
school='old boy'
t1=Teacher()
t1.name='sll'
t1.age=20
5、属性的增删改查
增加属性
对象变量名称.属性名称 = 属性值
删除属性
del 对象的变量名称.属性名称
修改
对象.属性 = 新的值
查看对象(加括号)属性 访问的是对象的所有属性 ,不包括类里面的,默认为空字典
print(对象.__dict__)
访问对象的类信息
print(对象.__class__)
访问类的属性
print(类.__dict__)#一大堆
#{'__module__': '__main__', '__doc__': '这是一个人类型', 'desc': '都会吃饭', 'name': '张三分', '__dict__': <attribute '__dict__' of 'Person' objects>, '__weakref__': <attribute '__weakref__' of 'Person' objects>}
__dict__就是名称空间
进一步解释:
四、初始化方法init
4.1、什么是初始化方法?
用于为对象的属性设置初始值的函数
class Student:
#school='old boy'
def __init__(self,school):#取代了之前所写school='old boy'
4.2、为什么需要初始化(为对象的属性设置初始值)?
在类的实例(对象)中,一些属性是必须存在的,就可以使用初始化函数来完成,比如Student
对象中的name
属性,它是必须的,用于唯一标识一个学生
class Student:
def __init__(self,name):
print('init run')
self.name=name#添加属性
-
会自动将对象作为第一个参数传入,参数名称位self 。可以将self改为其他任意的名称,但为了保证易读性通常是self,额外的参数须位于self之后
-
有了
__init__
方法,在创建实例的时候,就不能传入空的参数了,必须传入与__init__
方法匹配的参数,但self
不需要传,Python解释器自己会把实例变量传进去,如下案例演示:
#创建实例(对象)时必须传参
stu1=Student('sll')
练习:创建一个类具备几个属性,通过初始化方法来给他设置属性
class Dog:
def __init__(self,kind,colour,age):
self.kind=kind#第一个kind为属性,第二个为参数
self.colour=kind
self.age=age
d1=Dog('二哈','黑白',1)
d1=Dog('京巴','黑白',2)
注意:该函数不能有任何返回值/.... 只能是None 规定如此..
小结:
-
init函数用于为对象属性设置初始值
-
在创建对象时会自动调用
-
自动传入对象本身
五、对象的绑定方法
函数需要访问对象数据里内容,如下
#如何给类中函数传值
1.对象调用(对象.函数名())
stu1=Student('wuxi',18,male)#首先生成一个对象
stu1.say_hi()#对象点函数名的方式,无需传参。当使用对象调用该函数时会自动传入对象本身,作为第一个参数
2.通过类名调用(类.函数名(对象))
stu1=Student('wuxi',18,male)
Student.say_hi(stu1)#必须传对象。就是一个普通函数
默认情况下,类中的方法都是对象绑定方法
练习:写一个学生类,具备一个打招呼的技能 要能输出自己的名字信息
首先分析出,名字是属性,打招呼是技能
class Student:
def __init__(self,name):#自动执行。用于为对象的属性设置初始值
self.name=name
def say_hi(self):
print('hello my name is %s'%self.name)#此时需要访问对象数据里的name
p1=Student('wuxi')
p1.say_hi()
六、类的绑定方法
类绑定方法用@classmethod来装饰
举例证明@classmethod装饰函数(类绑定方法),则会自动传入类:
class OldBoyStudent:
school = "oldboy"
def __init__(self,name):
self.name = name
@classmethod
def show_school(cls):#将原先的self改成lcs,此时括号里的内容是类
# print(self.school)
print(cls)
OldBoyStudent.show_school()#cls的结果:类调用,原本是当做正常函数要传参的,但是自动传入类,因此不用传,下面一个打印结果是为了证明确实是自动传入的
print(OldBoyStudent)
"""
<class '__main__.OldBoyStudent'>
<class '__main__.OldBoyStudent'>
"""
# 两个打印结果证明了:类调用类绑定方法的函数会自动传入类本身
特殊之处:不管用类或对象调用,都会自动传入对象或类本身,作为第一个参数
什么时候绑定给对象:当函数逻辑需要访问对象中的属性时?
那对象都有些什么属性?
什么时候绑定给类:当函数逻辑需要访问类中的数据时?
那类中都有些什么数据?
class OldBoyStudent:
school = "oldboy"#这是类的属性,而不是对象的!!!!!!!!!!!!!!!!!
def __init__(self,name):
self.name = name
o1=OldBoyStudent('wx')
print(o1.__dict__)#{'name': 'wx'}
print(o1.__class__)#对象的类信息<class '__main__.OldBoyStudent'>
print(OldBoyStudent.__dict__):
# OldBoyStudent类的属性(字典):
{'__module__': '__main__', 'school': 'oldboy', '__init__': <function OldBoyStudent.__init__ at 0x0000000002229A60>, '__dict__': <attribute '__dict__' of 'OldBoyStudent' objects>, '__weakref__': <attribute '__weakref__' of 'OldBoyStudent' objects>, '__doc__': None}
补充(****):
类中定义变量和init的使用:
当类需要定义一个固定的属性,比如这个类的学生名字是固定的,那么就写在init外面,比如上面 的案例;若属性内容不固定就写在init里:
class OldBoyStudent:
school = "oldboy"#这个属性写在这里是因为:学生名字是固定的!
def __init__(self,name):
self.name = name#这个属性写在这里是因为:性内容不固定!
七、非绑定方法
或叫做静态方法,就是函数即不需访问类的数据,.也不需要访问对象的数据
语法:@staticmethod
class OldBoyStudent:
school = "oldboy"
def __init__(self,name):
self.name = name
@staticmethod
def show_school()
print('hello word')
#对象调用和类调用
OldBoyStudent.print_hello()
stu.print_hello()
总结:
为学生类添加一个save方法和一个get方法
class Student:
def __init__(self,name):#来一个属性
self.name=name
def say_hi(self):
print('name:',self.name)#传多个参数
def save(self):
# python数据搞到文件里,使用序列化,json不支持文件对象序列化,只好使用pickle
with open(self.name,'wb')as f :
pickle.dump(self,f)#pickle序列化的操作
@staticmethod
def get(name):
with open(name,'rb')as f:
obj=pickle.load(f)
return obj
stu=Student('WX')
stu1=Student('sll')
stu.save()
stu1.save()
obj=Student.get('wx')
print(obj.name)
八、属性的查找顺序
可以将类中的内容都称之为属性,变量称为数据属性,函数就叫函数属性
类中可以声明变量来表示数据属性,为Student
类添加数据属性和函数属性
class Student:
school = "sqxy" #数据属性
def say_hello(self):#函数属性
print("hello i am a student")
def __init__ (self,name): #初始化函数
self.name = name
也可以使用点语法在创建对象后为对象增加数据属性和修改属性(****)
stu=Student('wx')
stu.age=18