"""author = 陈俊龙"""
===============面向对象===============
1.编程思想
1)面向过程编程 工具:算法和逻辑
2)函数式编程 工具: 函数
3)面向对象编程 工具:类和对象 其实就是面向生活编程
面向过程求两数的和:
m = 1
n = 2
print(m+n)
m = 2
n = 3
print(m+n)
函数式编程求两数的和:
def sum1(m,n):
return m+n
sum1(10, 20)
sum1(20, 30)
面向对象编程求两数的和:
class Math():
def sum(self, m, n):
print(m+n)
def sub(self, m, n):
print(m-n)
math = Math()
math.sum(12, 90)
math.sub(10, 20)
===============类和对象================
1.什么是类,什么是对象
类:就是拥有相同功能和相同属性的对象的集合 - 抽象的
对象:就是类的实例 - 具体的
如果说人是一个类,具体的一个人就是对象,小明是另一个对象
2.类的声明:
1)语法:
class 类名:
类的内容
2)说明:
class
-- 关键字,固定写法
类名 :
-- 自己命名,但要求是标识符,不能是关键字。采用驼峰式命名,并且首字母要大写(规范)
StudentName
类的内容 :
-- 包含类的说明文档,类中的函数(相同的功能),类中的属性(相同的属性)
class Person:
"""类的说明文档:人类"""
def eat(self):
print('吃饭')
3.创建对象
1)语法:
对象 = 类()
创建Person类的对象:
p1 = Person()
创建Person类另一个的对象:
p2 = Person()
=================对象方法==============
1.类中的函数:
声明在类中的函数也叫方法,类中方法分为三种,分别是:对象方法,类方法,静态方法
1)对象方法:
直接声明在类中的函数,自带一个self参数。
对象方法需要通过 对象.函数名() 来调用
通过对象调用对象方法的时候,self不需要传参,系统将自动将当前对象传给self
class Person:
def eat(self):
# self = person1
print('吃饭')
self.run()
def run(self):
print('跑步')
def study(self, subject):
print('学习'+subject)
p1 = Person()
p1.run() # == Person.run(p1)
p1.eat()
p1.study('python')
# 注意: !不要!用类去调用对象方法
# Person.run()
print(Person.__dict__)
print()
print(Person().__dict__)
=================init方法===============
什么是init方法:
init:是类中的一个魔法方法,在创建对象的时候会被自动调用
class Person:
def __init__(self):
print('init方法被调用')
P1 = Person() # init方法被调用
P2 = Person() # init方法被调用
详细的过程:1.开辟空间,创建对象2.使用创建好的对象调用init方法(做一些初始化操作)3.返回对象
==============类中的属性==============
1.类中的属性:对象属性,字段
1)字段 -- 直接声明在类中(函数外)的变量
怎么使用:
通过 !类.字段 !来使用
什么时候使用:
属性值!不会!因为对象不同而不一样,这样的属性就声明为类的字段
2)对象属性
怎么声明:
以 !self.属性名 = 值! 的方式声明在init方法中
怎么使用:
通过 !对象.属性名! 的方式去使用
什么时候使用:
属性值!会!因为对象不同而不一样,这样的属性就声明为对象属性
class Person:
# num就是类的字段
num = 100
def __init__(self):
# 这里的name,age,gender就是Person类的对象的对象属性
self.name = ''
self.age = 0
self.gender = '男'
2. 使用类的字段:
p1 = Person() # 为什么加括号和不加括号一样?????
print(Person.num) # 100
print(p1.num) # 100
p2 = Person()
p2.name = '小明'
p3 = Person()
p3.name = '小花'
print(p2.name, p3.name) # 小明 小花
如果init方法除了self以外还有其他的参数,需要通过构造方法来给init()方法传参:
class Dog:
def __init__(self, name1, age1, color1, breed1):
self.name = name1
self.age = age1
self.color = color1
self.breed = breed1
dog1 = Dog('caicai', 12, 'red', 'tugou')
dog2 = Dog('hauhau', 2, 'bulu', 'tugou')
print(dog1.name) # caicai
print(dog1.age) # 12
重写repr方法来定制对象的打印格式(默认是对象的地址)
def __repr__(self):
return '定制打印对象格式'
class Student:
def __init__(self, name1, num, age1=18):
self.name = name1
self.age = age1
self.tel = 0
self.id = num
def __repr__(self):
reture '<%s>'%str(self.__dict__)[1:-1]
print(stu1) # 定制打印对象格式 注意是!对象
更改对象属性:
stu1 = Student('xi', '001')
stu1.tel = '12345' # 更改对象属性
print(stu1.tel) # 12345
练习:
声明一个矩形类,有属性长和宽,计算矩形的面积和周长
class Rec:
def __init__(self, len, hei):
self.len = len
self.hei = hei
def area(self):
return self.len*self.hei
def peri(self):
return (self.len+self.hei)*2
r1 = Rec(10, 20)
print(r1.area())
print(r1.peri())
例子:调用类的方法时额外传入参数:
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, str):
print('%s在吃%s' % (self.name, str))
p1 = Person('小红', 12)
p1.eat('面条')
============对象属性的增删改查==========
1.对象属性
python中的对象属性支持增删改查操作
增删改查操作只对当前对象有效,不会影响其他对象
2.查 - 获取对象属性的值
1)对象.属性
- 获取对象指定属性的值,如果属性不存在!会报错!
2)getattr(对象,属性名,默认值)
- 获取对象指定属性的值,如果属性不存在!不会报错!,而是返回默认值,注意用字符串来写属性名。
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def eat(self, str):
print('%s在吃%s' % (self.name, str))
p1 = Person('小红', 18)
p2 = Person('小明', 20)
# 获取对象属性:
print(p1.name) # 小红
print(p2.name) # 小明
print(getattr(p1, 'name', '001')) # 注意用字符串来写属性名 小红
3.增,改 - 给对象添加属性或者修改对象属性的值
1)对象.属性 = 值
- 当属性不存在就给对象添加属性,如果存在就修改对象属性的值
2)setattr(对象,属性,值) - 当属性不存在就给对象添加属性,如果存在就修改对象属性的值
# 修改
p1.name = '小李'
print(p1.name) # 小李
setattr(p1, 'name', '小张')
print(p1.name) # 小张
# 添加
p1.id = 1234
print(p1.id) # 1234
4. 删 - 删除对象属性
1)del 对象.属性
2)delattr(对象,属性)
del p1.id
# print(p1.id) # AttributeError: 'Person' object has no attribute 'id'
delattr(p1, 'age')
# print(p1.age) # AttributeError: 'Person' object has no attribute 'id'
可以通过给类的 slots 字段赋值,来约束当前类的对象最多有哪些属性
class Dog:
# 可以通过给类的 __slots__ 字段赋值,来约束当前类的对象最多有哪些属性
__slots__ = ('name', 'age', 'color')
def __init__(self, name, age, color):
self.name = name
self.age = age
self.color = color
def eat(self, str):
print('%s在吃%s' % (self.name, str))
# d1 = Dog('caicai',18,'red') # AttributeError: 'Dog' object has no attribute 'color'
===============内置内属性==============
1.什么是内置类属性
创建类的时候,系统自动为这个类创建的属性
class Person:
"""说明文档:人类"""
num = 100
def __init__(self, name, age=0, gender='女'):
self.name = name
self.age = age
self.gender = gender
def eat(self, food):
print('%s在吃%s' % (self, food))
def __repr__(self):
return str(self.__dict__)
# def __str__(self): 很少用
# return str(self.__dict__)
p1 = Person('tom', 18, '男')
name -- 类的字段,获取类的名字
print(Person.__name__) # Person
doc -- 类的字段,获取类的说明文档
print(Person.__doc__) # 说明文档:人类
print(int.__doc__)
class -- 对象属性,获取对象对应的类
print(p1.__class__) # 这个结果和类功能是一样的
dict -- 当作为类的字段,获取类的字段(用的少),作为对象属性,获取所以属性和其对应的值,并以字典形式返回
注意:如果给类的slots赋了值,那么这个内置的属性就没有了,需要取舍
print(Person.__dict__)
print(p1.__dict__) # {'name': 'tom', 'age': 18, 'gender': '男'}
运用了repr后的效果:
print(p1) # {'name': 'tom', 'age': 18, 'gender': '男'}
module -- 类的字段,获取声明类所在的模块的名字
print(Person.__module__) # __main__ 因为在当前模块,所以显示__main__
print(int.__module__) # builtins
bases -- 类的字段,获取当前类的父类
print(Person.__bases__) # (,)
验证 slots 使用的影响:
class Person:
"""说明文档:人类"""
num = 100
# __slots__ = ('name', 'age', 'gender')
def __init__(self, name, age=0, gender='女'):
self.name = name
self.age = age
self.gender = gender
p1 = Person('tom', 18, '男')
print(p1.__dict__)
list4 = (x for x in range(10) if x % 2)
print(list4)