一,编程思想
1.面向过程编程 - 遇到问题直接将逻辑转换成代码
2.函数式编程 - 遇到问题就像找一个,写一个拥有相应功能的函数;以函数作为编程工具
3.面向对象编程 - 遇到问题就考虑可不可以有一个类来给我提供相应的功能和数据;以类和对象为编程工具
python既支持函数式编程也支持面向对象编程
# 面向过程
num1 = 34
num2 = 34
print(num1+num2) # 万一求另两个那不是又重要写,麻烦
# 函数式编程
def sum1(num1, num2):
return num1+num2
print(sum1(3, 34)) # 下次再求和直接输入数字就行了,不用重写代码,方便
二 认识类和对象(声明) 重点
1.什么是类, 什么是对象
类就是拥有相同功能和相同属性的对象的集合;类是抽象的
对象就是类的实例;对象是具体的
人是类, 唐浩就是人类的对象
车是类, 楼下停在...的那辆车就是对象
电脑是类, 我桌上这台黑色的电脑就是对象 (电脑很多颜色,型号成千上万所有是抽象的, 面前的电脑就是具体的体现)
2.类的声明
类中的内容包含功能(函数)和属性(变量/属性)
a.语法
class 类名:
类的内容
b.说明
class - python声明类的关键字
类名 - 要求: 标识符, 不能是关键字
规范: 驼峰式命名(通过首字母大写来区分不同的单词);第一个字母要大写
" - 固定写法
类的内容 - 包含类的说明文档,属性和方法
属性就是声明在类中的变量
方法就是声明在类中的函数
userName
UserName -类名 (都是驼峰式命名)
user_name - pep8
3.对象的声明
语法:
类名() - 创建指定的类的对象并且返回
# 声明一个人类
class Person:
"""类的说明文档: 人类"""
num = 61 # 类中的属性 也叫类的字段
# 类中的方法
def eat(self): # eat就是类的变量
print('人在吃饭')
# 创建Person类的对象;p1就是对象
p1 = Person()
print(p1) # 类默认打印的都是地址
# 同一个类可以创建多个对象
p2 = Person()
print(p2) # 此时地址不同,因为类是抽象的,有很多
p3 = p2
print(p3) # 和p2的地址相同
三 对象方法
class 类名:
类中的属性
类中的方法
1.类中的方法
声明在类中的函数就是方法
类中的方法包括: 对象方法(实例方法), 类方法, 静态方法
2.对象方法:
a. 什么是对象方法
直接声明在类中的函数就是对象方法
有默认参数self
调用
通过'对象.方法()'的方式来调用(对象方法要通过对象来调用) 里面的方法就是函数变量名
b.参数self
当我们通过对象调用对象方法的时候,self不需要传参, 因为系统会自动将当前对象传递给self。
当前对象: 调用当前方法的对象(谁调用对象方法self就是谁)
注意: 当前类的对象能做的事情self都可以做 谁调用self就是谁
class Person:
def run(self):
# self = p1
print('=====2swswsw====')
print('self', self) # self <__main__.Person object at 0x02113830> *3
print('人在跑步')
def eat(self, food):
print('self2', self) # <__main__.Person object at 0x00613830> *7
print(food)
# run() # name 'run' is not defined会报错,因为在类里面不能再外面调用
def main():
print('=======') # 打印顺序*1
# 创建对象
p1 = Person()
# 通过对象p1调用对象方法
print('p1', p1) # 就是和self一样 p1 <__main__.Person object at 0x02113830> *2
p1.run() # 人在跑步 不用传参,传参之后(默认有个self)会有两个参数会报错 p1就是当前对象 *4
# 调用对象方法只需要给出了self以外的其他参数传参
print('======-----=======') # *5
p1.eat('包子')
print(p1) # *6
if __name__ == '__main__':
main()
四 init方法和构造方法
1.init方法: __init__
init方法是类中的一个特殊的对象方法, 专门用来对创建的对象进行初始化。
当通过类创建对象的时候,系统就会自动调用__init__方法
2.构造方法
a.什么是构造方法
函数名和类名一样的函数就是构造方法, 专门用来创建对象。
python中声明类的时候系统会自动创建这个类对应的构造方法
b.构造方法的执行过程
当我们构造方法的时候内部会先在内存中开辟空间保存对象;然后用创建的这个对象去调用--init--方法,用来对对象进行初始化;
--init--方法调用结束后,返回对象.
内部操作:
def Person(*args, **kwargs):
对象 = 创建对象
对象.__init__(*args, **kwargs)
return 对象
注意: 如果类的init除了self以外还有其他参数,那么我们在创建对象的时候需要给构造方法来给init方法传参
class Person:
# 类中两个__开头并且__结尾的方法叫魔法方法。不需要主动调用,系统会自动调用
def __init__(self):
print('init被调用了')
class Dog:
def __init__(self, x, y):
print(x, y)
print('dog的init')
# ==============构造方法和init的关系(了解)==============
# 构造方法的伪代码
def my_init(a, b):
print('a', a, b) # a 12 32
print('my_init')
def my_Dog(*args, **kwargs):
my_init(*args, **kwargs)
my_Dog(a=12, b=32)
# =====================================
def main():
# 人类
print('======')
p1 = Person() # init被调用了 这就是构造方法
print('======')
p2 = Person() # init被调用了
# 狗类
dog1 = Dog('金毛', '花狗') # 金毛 花狗 /n dog的init self不需要传参
if __name__ == '__main__':
main()
五 对象属性
重要!!!
1.什么是对象属性
类中的属性分为类的字段和对象属性
a.对象属性 - 属性的值会因为对象不同而不一样,这种属性就应该声明为对象属性
声明在init方法中 - 位置
以'self.属性名 = 值'的方式来声明(这儿的属性就是对象属性,值随便赋值) - 方式
通过'对象.属性名'的方式来使用 - 使用
b.类的字段 - 属性的值不会因为对象不同而不同,这种属性就声明成类的字段
直接声明在类的里面,函数外面的变量就是类的字段
以'字段名 = 值'
通过'类.字段'的方式来使用
class Person:
# 类的字段
num = 61
Person.num = 100
# 修改类的字段的值
print(Person.num)
class Person:
# 在init方法中声明对象属性
def __init__(self):
self.name = '张三' # 这就是对象属性
self.age = 18 # 这就是对象属性
p1 = Person()
# 获取对象属性的值
print(p1.name, p1.age) # 张三 18
p2 = Person()
# 修改对象属性的值
p2.name = '李四'
print(p2.name, p1.age) # 李四 18
class Person:
# 在init方法中声明对象属性
def __init__(self, name1='', age1=0):
self.name = name1 # 这就是对象属性 name就是属性
self.age = age1 # 这就是对象属性 age就是属性
p1 = Person('小明', 18)
# 获取对象属性的值
print(p1.name, p1.age) # 小明 18
p2 = Person('小心', 20)
# 修改对象属性的值
p2.name = '李四'
print(p2.name, p2.age) # 李四 20
# 练习: 创建Dog类,有属性名字, 类型, 年龄 (都是对象属性)
# 要求创建Dog的对象的时候:不能给年龄赋值,可以给类型赋值也可以不用给类型赋值,必须给名字赋值
# 添加对象方法eat:打印XXX在吃什么
class Dog:
def __init__(self, name1='', type=''):
self.name = name1
self.type = type
self.age = 0
def eat(self, food):
# self = dog1, food = '骨头'
# self = dog2, food = '屎'
print('%s在吃%s' % (self.name, food))
dog1 = Dog('小迪', '金毛')
print(dog1.name, dog1.type, dog1.age)
dog1.eat('骨头')
dog2 = Dog('旺财', '中华田园犬')
dog2.eat('屎')
练习:声明一个矩形类,拥有属性长和宽,拥有方法求面积和求周长
class Rect:
def __init__(self, length, width):
self.length = length
self.width = width
def perimeter(self):
perimeter =(self.width + self.length) * 2
print('矩形的周长是%d' % perimeter)
def area(self):
mianji = self.length * self.width
print('矩形的面积是%d' % mianji)
rect1 = Rect(8, 9)
rect1.perimeter()
rect1.area()
六 对象属性的增删改查
python中对象中对象的属性支持增删改查
1.查(获取对象属性)
对象.属性
__XX__这就叫魔法方法
# 属性的增删改查
class Person:
def __init__(self, name='', age=0, sex='女'):
self.name = name
self.age = age
self.sex = sex
class Dog:
# __slots__魔法
# 约束当前类的对象最多能拥有那个属性
__slots__ = ('name', 'color', 'age')
def __init__(self, name='', color='黑色'):
self.name = name
self.color = color
def main():
dog1 = Dog('大黄', '黄色')
dog1.age = 2 # 有了__slots__就会报错,要想正确在__slots__添加'age'
dog1.name = 'ss'
print('================元素的增删改查============')
p1=Person('小花')
p2=Person('小红')
p3=Person('小强')
# 查
"""
对象.属性 - 获取指定对象指定属性值;当属性不存在的时候会报错
getattr(对象, 属性名:str) - 获取指定对象指定属性值
当属性不存在的时候如果给默认值赋了值,程序不会报错,并集将默认值作为结果
"""
print(p1.name) # 小花
# 属性不确定的时候可以用getattr
# attr = input('属性:')
# print(getattr(p1.attr))
# print(p1.name1) # 报错 'Person' object has no attribute 'name1 属性不存在
print(getattr(p1, 'name')) # 小花
# print(getattr(p1, 'name1')) # 也会报错 'Person' object has no attribute 'name1 属性不存在,但可以通过N后面加默认值补救
print(getattr(p1, 'name1', '小心')) # 小心
# 增/改
"""
对象.属性 = 值 - 当属性存在的是修改属性的值;属性不存在的时候添加属性
setattr(对象, 属性名, 值) - 当属性存在的是修改属性的值;属性不存在的时候添加属性
"""
print('===========增/改============')
# 修改属性
p1.name = 'xiaohua'
print(p1.name)
# 添加属性
p1.height = 180
print(p1.height)
setattr(p1, 'age', 28)
print(p1.age)
setattr(p1, 'weight', 200)
print(p1.weight)
# 删
"""
del 对象.属性
delattr(对象, 属性名)
"""
print('==========删============')
del p1.sex
# print(p1.sex) # 'Person' object has no attribute 'sex' 因为删了就没了
delattr(p1, 'age')
# print(p1.age) # 'Person' object has no attribute 'sex' 因为删了就没了
# 注意:对象属性的操作,只针对操作的那一个对象,不会影响其他对象
# 如上面p1的增删 不会影响p2
if __name__ == '__main__':
main()
七 内置属性
内置属性指的是我们创建类的时候系统自动给我们添加的属性(其实是通过继承获取到的)
class Person:
"""说明文档:人类"""
# 类的字段
num = 61
# __slots__ = ('name', 'age', 'sex') # 一打开对象的__dict__就不能使用,会报错
# 对象属性
def __init__(self, name='', age=0, sex='男'):
self.name = name
self.age = age
self.sex = sex
def eat(self, food):
print('%s在吃%s' % (self.name, food))
# 定制对象的打印格式(当我们通过print打印一个对象的时候,实质就是打印对象调用__repr__函数的返回值)
# 这个函数的返回值必须是字符串
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 main():
p1 = Person('小明', 18)
print(p1) # print(p1.__repr__()) # <'name': '小明', 'age': 18, 'sex': '男'at0x2ec330>
# 1.类.__name__ 获取的名字(字符串)
print(Person.__name__, type(Person.__name__)) # Person <class 'str'>
# 此时Person.__name__是字符串而不是类
class_name = Person.__name__
print(Person, class_name) # <class '__main__.Person'> Person
print(Person.__name__.upper()) # PERSON
print('==========')
# 2.对象.__class__ - 获取对象对应的类(结果是类)
# 获取对象p1的类
my_class = p1.__class__
print(my_class) # <class '__main__.Person'>
# 可以将my_class当成类来使用
p2 = my_class('小花')
print(my_class.num) # 61
# 3.类.__doc__ -获取类的说明文档(字符串)
print(Person.__doc__) # 说明文档:人类
# 获取对象p1对应的类的说明文档
print(p1.__class__.__doc__) # 说明文档:人类
# 4.对象.__dict__ - 将对象转换成字典,将属性和值作为字典的键值对,
# 可以查看对象的不同
# 注意: 当给__slots__属性赋值后, 对象的__dict__属性就不能使用
print(p1.__dict__) # {'name': '小明', 'age': 18, 'sex': '男'}
# 5.类.__module__ - 获取当前所在的模块的模块名
print(Person.__module__) # __main__如果没有if那句就是07内置属性
# 6.类.__bases__ - 获取当前类的父类(元祖)
print(Person.__bases__) # (<class 'object'>,) object就是它的父类, 相当于有几个父亲
if __name__ == '__main__':
main()
八 对象方法,类方法和静态方法的区别
1.对象方法:
a.怎么声明: 直接声明在类中
b.特点: 自带self参数,调用的时候不用传参,谁调用指向谁
c.怎么调用: 对象.方法()
2.类方法
a.怎么声明:声明函数前加@classmethod
b.特点: 自带默认参数cls; 调用的时候不用传参,系统会自动将调用函数的类传给它
(cls是谁调用就指向谁,类方法只能通过类来调用,所以cls就是当前类)
类能做的事情, cls都能做
c.怎么调用:通过类来调用, 类.方法()
方法就就是类中函数的变量名
3.静态方法
a.怎么声明: 声明函数前加@staticmethod
b.特点: 没有默认参数
c.怎么调用: 通过类来调用,类.方法()
4.类中怎么选择使用哪种方法:
如果实现类中的函数的功能需要使用对象的属性,那么这个函数就要声明 对象方法
实现函数的功能不需要使用对象的属性的前提下,如果需要类的字段, 就声明成 类方法
实现函数的功能既不需要对象属性也不需要类的字段就声明成 静态方法
class Person:
num = 61
@staticmethod
def func3():
print(Person.num)
print('我是静态方法')
@classmethod
def func2(cls):
print(cls.num)
print('我是类方法2')
@classmethod
def func1(cls):
# 说明类能做的,cls都能做
p1 = cls() # 用cls来创建对象
print(p1)
cls.num = 100 # cls来使用类的字段
cls.func2() # cls调用类方法
print('cls:', cls)
print('这是一个类方法')
def main():
Person.func1() # 这是一个类方法 类.方法(函数变量名)
Person.func3() # 我是静态方法
if __name__ == '__main__':
main()
class Game(object):
# 游戏最高分,类属性
top_score = 0
@staticmethod
def show_help():
print("帮助信息:让僵尸走进房间")
@classmethod
def show_top_score(cls):
print("游戏最高分是 %d" % cls.top_score)
def __init__(self, player_name):
self.player_name = player_name
def start_game(self):
print("[%s] 开始游戏..." % self.player_name)
# 使用类名.修改历史最高分
Game.top_score = 999
# 1. 查看游戏帮助
Game.show_help()
# 2. 查看游戏最高分
Game.show_top_score()
# 3. 创建游戏对象,开始游戏
game = Game("小明")
game.start_game()
# 4. 游戏结束,查看游戏最高分
Game.show_top_score()
网友评论