什么是类,什么是对象
-
什么是类,什么是对象
类就是拥有相同功能和相同属性的对象的集合;类是抽象的对象就是类的实例;对象是具体的
人是类, 郭锐就是人类的对象
-
类的声明
类中的内容包含功能(函数)和属性(变量/属性)- 语法
class 类名:
类的内容 - 说明
class - python声明类的关键字
类名 - 要求:标识符、不能是关键字
规范:驼峰式命名 ,类名首字母大写、
: - 固定写法
类的内容 - 包含类的方法、属性和说明文档
方法就是声明在类中的函数,
属性就是声明在类中的变量
- 语法
-
对象的声明
语法:
类名() - 创建指定的类的对象# 声明一个人类 class Person: """类的说明文档:人类""" num = 61 def eat(self): print('人在吃饭') # 创建Person类的对;p1就是person的对象 p1 = Person() p1.eat()
对象方法
class 类名:
类的属性
类的方法
类中的方法
声明在类中的函数就是方法
类中的方法包括:对象方法(实例方法),类方法,静态方法-
对象方法:
- 什么是对象方法
直接声明在类中的方法就是对象方法
有默认参数self
通过 对象.方法 的方式来调用(对象方法要通过对象来调用) - 参数
当我们通过对象调用对象方法的时候,self不需要传参;因为系统会将当前对象传递给self
当前对象: 调用当前方法的对象(谁调用对象方法的时候 self就是谁)
调用对象方法只给除self以外的参数传参
class Person: def run(self): # print(self) print('人在跑步') def eat(self, food): self.run() print(food) def main(): # 创建对象 p1 = Person() # print(p1) # 通过对象p1调用对象方法 # p1.run() p1.eat('鸡腿') if __name__ == '__main__': main()
- 什么是对象方法
init方法和构造方法
init方法: init
init方法是类中的一个特殊的对象方法,专门用来对创建的对象进行初始化的。
当通过类创建对象的时候系统会自动调用init方法-
构造方法
什么是构造方法
函数名和类名相同的函数就是构造方法,专门用来创造对象
python中声明类的时候,系统会自动创建这个类对应的构造方法-
构造方法的执行过程
当我们调用构造方法创造对象的时候,内部会先在内存中开辟空间保存对象,然后用创建的这个对象调用init方法对对象进行初始化
init方法调用结束后,返回对象def Person():
对象 = 创建对象
对象.init()
return 对象
注意:如果类的init方法除了self以外还有其他参数,那么我们在创建对象的时候需要通过给构造方法来给init方法传参class Person: # 类中两个下划线开头并且两个下划线结尾的方法叫魔法方法,不需要主动调用,系统会自动调用 def __init__(self): print('__init__被调用了') class Dog: def __init__(self, x, y): print('dog的init') # 构造方法伪代码 def my__init__(a, b): print(a, b) print('my__init__') def my_dog(*args, **kwargs): my__init__(*args, **kwargs) my_dog(a=10, b=20)
对象属性
-
什么是对象属性
类中的属性分为类的字段和对象属性- 对象属性 - 属性的值会因为对象不同而不一样,这种属性就应该声明为对象属性
声明在init方法中 - 位置
以'self.属性 = 值'的方式类声明(这儿的属性就是对象属性) -- 方式
通过对象.属性的方式来使用 - 类的字段 - 属性的值不会因为对象的不同而不同,这种属性就声明成类的字段
直接声明在累的里面,函数的外面的变量
以'字段名 = 值'
通过 '类.字段' 的方式来使用
class Person: def __init__(self, name, age): self.name = name self.age = age # 练习:创建dog类,有属性名字,类型,年龄 # 创建Dog类的时候不能给年龄赋值可以给类型赋值,也可以不用给类型赋值,必须给名字赋值 # 对象方法eat:打印xxx在吃什么 class Dog: def __init__(self, name, type='哈士奇'): self.name = name self.age = 3 self.type = type def eat(self, food): print(self.name + ' is eating ' + food) # 练习声明一个矩形,类,拥有属性长、宽,方法面积和周长 class Rectangle: num = 52 def __init__(self, length=4, width=3): self.length = length self.width = width def per(self): return 2*(self.length + self.width) def area(self): return self.length * self.width def main(): p1 = Person('张三', 20) print(p1.name, p1.age) p2 = Person('郭锐', 18) print(p2.name, p2.age) dog1 = Dog('郭锐', type='中华田园犬') dog1.eat('shit') rec1 = Rectangle() print(rec1.per()) print(rec1.area()) rec1 = Rectangle(length=8, width=6) print(rec1.per()) print(rec1.area()) print(rec1.num)
- 对象属性 - 属性的值会因为对象不同而不一样,这种属性就应该声明为对象属性
对象属性的增删改查
python中对象的属性支持增删改查
class Person:
def __init__(self, name='', age=0, sex='女'):
self.name = name
self.age = age
self.sex = sex
class Dog:
# __slots__ slots魔法
# 约束当前类的对象最多能拥有的属性
__slots__ = ('name', 'color')
def __init__(self, name='', color='black'):
self.name = name
self.color = color
def main():
p1 = Person('郭锐')
p2 = Person('孙悟空')
# 1.查
"""
对象.属性 - 获取指定对象属性值;当属性不存在的时候回报错
getattr(对象, 属性名:str, 默认值) - 获取指定对象指定属性值;
当属性不存在的时候,如果给默认值赋值,程序不会报错,并且将默认值作为结果。
若不赋值,就会报错
"""
print(p1.name)
print(getattr(p1, 'name', None))
print(getattr(p1, 'name', None))
# 属性不确定的时候使用getattr
# 增/改
"""
对象.属性 = 值 - 当对象属性存在时修改属性的值, 属性不存在的时候添加属性
setattr(对象, 属性名, 值) - 当属性存在的时候修改属性的值;不存在的时候添加
"""
print('===============增、改====================')
p1.name = '郭小瑞'
print(p1.name)
# 添加属性
p1.height = 180
print(p1.height)
setattr(p1, 'height', 179)
setattr(p1, 'weight', 180)
print(p1.name, p1.age, p1.height, p1.weight)
# 删
print('================删除=======================')
"""
del 对象.属性
delattr(对象, 属性名)
"""
del p1.sex
# print(p1.sex)
# delattr(p1, 'sex')
# 对象指定的操作,只针对的哪一个对象,你不会影响其他对象
# python中的对象支持 增删改查
dog1 = Dog('大黄', 'yellow')
内置属性
内置属性指的是我们创建类的时候系统自动个哦我们添加的属性(其实是通过继承获取到了)
class Person:
"""人类"""
num = 61
# __slots__ = ('name', 'age', 'sex')
def __init__(self, name='', age=0, sex='男'):
self.name = name
self.age = age
self.sex = sex
# 定制对象的打印格式(当我们通过print打印一个对象的时候,实质就是打印对象调用__repe__的返回值)
# 这个函数的返回值是字符串
# def __repr__(self):
# # return '{%s.%s object at %s}' % (self.__class__.__module__, self.__class__.__name__, hex(id(self)))
# return str(self.__dict__)[1:-1] + 'at' + hex(id(self))
def eat(self, food):
print('%s在吃%s' % (self.name, food))
def main():
"""
1.类.__name__ - 获取的名字
"""
p1 = Person('郭锐')
print(Person.__name__)
# 值是一个字符串, 可以当成字符串
class_name = Person.__name__
print(Person, class_name.upper())
"""
2.对象.__class__ - 获取对象对应的类
"""
# 获取对象p1的类
my_class = p1.__class__
print(my_class)
# 可以将他当做类来使用
p2 = my_class('大黄')
print(my_class.num)
"""
3.类.__doc__ - 获取类的说明文档(str)
"""
print(my_class.__doc__)
print(int.__doc__)
"""
4.对象.__dict__ - 将对应的对象转换为字典。将属性和值作为字典的键值对(字典)
"""
# setattr(p1, 'height', 18)
print(p1.__dict__)
# 当给slots赋值后,对象的__dict__的属性就不能使用
# print(Person.__dict__)
"""
5.类.__module__ - 获取当前类所在的模块的模块名
"""
print(Person.__module__)
"""
6.类.__bases__ - 获取当前类的父类(元组)
"""
print(Person.__bases__)
print(p1.__repr__())
persons = [Person('p2', 12), Person('p3', 18, 'nv')]
print(persons)
类方法和静态方法
-
对象方法:
- 怎么声明:直接声明在类型
- 特点:知道self参数,调用的时候不用传参
- 怎么调用:对象.方法()
-
类方法:
- 怎么声明: 声明函数前加@classmethod
- 特点:自带cls默认参数,调用的不用传参,系统会自动将调用当前函数的类传给他
(cls是谁调用就指向他)
类能做的事情cls都可以做, - 怎么调用:通过类来调用, 类.方法()
-
静态方法:
- 怎么声明: 声明函数前加@staticmethod
- 特点: 没有默认参数
- 怎么调用:通过类来调用, 类.方法()
-
在类中怎么选择使用哪种方法
如果实现类中函数的功能需要使用对象的属性,那么这个函数就要声明成对象方法
如果实现函数的功能不需要使用对象属性的嵌套下,如果需要类的字段,就声明成类方法
如果实现函数的功能既不需要对象属性也不需要类的字段就声明成静态方法class Person: num = 61 def __init__(self): self.name = '张三' def func4(self): print('%s对应的对象' % self.name) print('人类的数量:%d亿' % Person.num) @classmethod def fun2(cls): print('我是第二个类方法') @classmethod def func1(cls): # 通过cls创建对象 p1 = cls() print(p1) print('cls:', cls) print('这是一个类方法') cls.num = 100 # cls来使用类的方法 print(cls.num) cls.fun2() # cls调用类方法 @staticmethod def func3(): print('这是一个静态方法')