面向过程
着眼于具体的细节
面向对象
着眼于某一种特殊功能的方法
类和对象是面向对象的核心
面向过程与面向对象区别与联系
类
物以类聚,人以群分
将一个具有相同功能,称之为一个类
类用于描述某一个对象的共同特征
对象
一个类中,具有特殊功能的实体 ,是类的具体存在
例子:
假设狗设为一个类
类属性:毛的颜色。名字
方法:狗会咬人,会叫,会吃
封装 对象=属性+方法
实例化对象
类的语法
class 类名():
类体
设计类,三大步:
1.事物的名称 – 类名
2.事物的特征-属性 – 属性
3.事物的行为 --方法
构造函数(Python内置的函数)
# 实例化对象时,会自动调用此函数
# 作用:初始化处理对象属性
def __init__(self):
pass
析构函数
# 当对象被销毁的时候自动调用
def __del__(self):
pass
有关self
1.self代表对象自己本身
2.定义函数self必须声明,传递参数的时候我们无需传递此参数,
对象会将自己作为第一个参数传递进去
3.self并不是一个关键字,是一种约定俗成的写法/也可自定义
4.self定义的位置一定是参数列表中的第一个位置
创建简单类
class Dog:
def __init__(self,name,color):
self.name = name
self.color = color
def eat(self):
print('大狗狗吃狗粮!')
def biter(self):
print('谁来咬谁!')
if __name__ == '__main__':
dog = Dog('大黄','黄色')
dog.eat() # 大狗狗吃狗粮
print(dog.name) # 大黄
print(dog.color) # 黄色
类变量(类属性)
定义在类中,并且在函数体之外的变量,我们称之为类变量,类变量一般情况建议使用类名来进行调用,但是
若使用对象来进行调用也不报错
成员变量(类属性)
定义在类的函数中,并且绑定在self身上的变量,我们称之为成员变量,
成员变量一定使用对象来进行调用的,不能使用类名来进行调用
类变量以及成员变量的区别:
1.定义的位置不同 类变量定义在类中的函数体之外,成员变量定义在类的函数中并且绑定在self身上的变量
2.访问的方式不同 成员变量必须使用对象来访问,类变量使用类名来访问,也可以使用对象
3.在内存中出现的时机不同 类变量随着类的加载创建,而成员变量随着对象的创建而创建
4.优先级不同 当使用对象来访问类变量与成员变量的时候,优先访问成员变量。
通过对象动态添加类变量
通过对象动态添加/修改类变量
class Person:
age = 20
def __init__(self,name):
self.name = name
def say():
print("hello")
if __name__ == '__main__':
# 创建对象per
per = Person('王五')
per.color = '黄色'
# 动态添加类变量
print(per.color) # 黄色
# 通过对象更改类变量,其实是动态创建了一个跟类变量同名的变量
per.age=25
print(per.age) # 25
# 加载类方法
per.say() # hello
# 创建对象per2
per2 = Person('王五')
# 由对象per修改的类变量并没有真正的修改
print(per2.age) # 20
# 用类修改类变量
Person.age = 33
print(per2.age) # 33
# 创建对象per3
per3 = Person('王五')
# 通过类修改的类变量,在其他对象中,也会跟着改变
print(per3.age) # 33
总结:
我们可以动态给对象或者是类绑定属性以及方法
1.使用对象动态绑定属性以及方法的时候,只对当前对象起作用,
若是使用类名来进行绑定,对整个类起作用
2.使用对象可以调用类变量 不能直接修改类变量(通过类可以修改类变量的值),我们看到的对类变量的更改,
其实是创建一个新的变量,这个新的变量与类变量同名,使用对象来更改的类变量,只对当前对象起作用。
slots_ 对当前类的dongtai方法和动态成员变量进行限制,能够动态添加的属性名(包括__init__中的类属性,如果不加,将抛出异常)以及方法名加入slots中
class Person:
# 将可以动态修改的的成员变量和方法加入__slots__中
__slots__ = ("name")
age = 20
def __init__(self, name):
self.name = name
def say():
print("hello")
if __name__ == '__main__':
per = Person('赵六')
# 未加入__slots__ 中,不能够动态加载
per.say() # 报错 'Person' object has no attribute 'say'
per.name = '钱七'
print(per.name)
# 当类中加了 __solts__后,不能直接通过对象更改类变量
per.age = 22 # 报错 'Person' object attribute 'age' is read-only
成员方法
1.一般情况下定义在类中的方法,都是成员方法,不需要任何装饰器来进行装饰,
调用的时候使用对象来进行调用,不能使用类名调用。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print("hello")
if __name__ == '__main__':
per = Person("lili",20)
# Person.say() # 报错
静态方法
1.当一个普通的方法,写在类中 与 写在类的外面写法都是相同,这个函数我们就可以将其写为静态方法
使用@staticmethod装饰器来进行装饰
调用的时候建议使用类名来进行调用,若使用对象来进行调用也不报错(跟类方法一样:@classmethod)
from datetime import datetime
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def say(self):
print("hello")
@staticmethod
def welcome(name):
print("欢迎光临....%s"%name)
if __name__ == '__main__':
print(datetime.now())
per = Person("lili",18)
per.welcome("xiaoming")
Person.welcome("xiaohua")
类方法
类方法不是绑定到对象上,而是绑定在类上的方法
1.类方法是给我们的类准备的,调用的时候建议 使用类名 来进行调用(跟静态方法一样:@staticmethod)
使用对象来进行调用也不报错,但是有时候会让人引起误解
2.什么时候使用类方法?
.当在这个函数中,使用到类变量,类方法,静态方法的时候我们可以将此函数写成类方法
.类方法使用:@classmethod装饰器来进行装饰
from datetime import datetime
class Person:
sex = 'boy'
def __init__(self,name,age):
self.name = name
self.age = age
def say(self):
print('English')
@classmethod
def getSex(cls):
print(cls) # <class '__main__.Person'>
print(cls.sex) # boy
cls.welcome()
@staticmethod
def welcome():
print('欢迎光临!')
if __name__