Python编程基础
Posted 雨宙
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python编程基础相关的知识,希望对你有一定的参考价值。
Python编程基础(三)
打卡第三天啦!!!
面向对象基础(上)
面向对象介绍
- OOP
- 将数据与函数绑定在一起,进行封装
- 面向过程和面向对象
类和对象
- 类是模板,由类名、属性、方法构成
- 对象是根据模板创建的实例
定义类和对象
# 类名用大驼峰命名法
class Person:
name='潘小雷'
age=20
def watch(self):
print('看韩剧')
pass
def run(self):
print('跑步')
pass
# 创建对象
rainy_universe=Person()
print(rainy_universe.name)
print(rainy_universe.age)
rainy_universe.watch()
rainy_universe.run()
# 潘小雷
# 20
# 看韩剧
# 跑步
实例方法与属性
- 在类的内部,使用def关键字可以定义一个实例方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数(名字可以不是self,但是这个位置必须被占用)
- 属性:类里面定义的变量(类属性)
- 定义在方法里面使用self引用的属性称之为实例属性
# 类名用大驼峰命名法
class Person:
def watch(self):
print('看韩剧')
pass
def run(self):
print('跑步')
pass
def __init__(self):
self.name='潘小雷' # 实例属性
self.age=20
# 创建对象
rainy_universe=Person()
print(rainy_universe.name)
print(rainy_universe.age)
rainy_universe.watch()
rainy_universe.run()
# 潘小雷
# 20
# 看韩剧
# 跑步
__init__方法
- python自带的内置函数,是魔术方法
- 是一个初始化的方法,用来定义实例属性和初始化数据的,在创建对象的时候自动调用,不用手动去调用
- 利用传参的机制可以让我们定义功能更强大并且方便的类
# 使用__init__方法前
class People:
def eat(self):
print('俺在吃饭')
pass
rainy_universe=People()
rainy_universe.eat()
rainy_universe.name='雨宙'
rainy_universe.age=19
print(rainy_universe.name,rainy_universe.age)
pan=People()
pan.name='潘小雷'
pan.age=20
print(pan.name,pan.age)
# 俺在吃饭
# 雨宙 19
# 潘小雷 20
# 使用__init__方法后
class People:
def __init__(self):
self.name='潘小雷'
self.age=20
pass
pan=People()
print(pan.name,pan.age)
# 潘小雷 20
rainy_universe=People()
rainy_universe.name='雨宙'
rainy_universe.age=19
print(rainy_universe.name,rainy_universe.age)
# 雨宙 19
# 改进
class People:
def __init__(self,name,age):
self.name=name
self.age=age
pass
def eat(self,food):
print(self.name+'在吃'+food)
pass
pan=People('潘小雷',20)
print(pan.name,pan.age)
pan.eat('面条')
# 潘小雷 20
# 潘小雷在吃面条
理解self
- self和对象指向同一个内存地址,可以认为self就是对象的引用
class Person:
def eat(self):
print(self)
print('self='.format(id(self)))
pass
pass
pan=Person()
pan.eat()
print('pan='.format(id(pan)))
# <__main__.Person object at 0x000002449D31FFA0>
# self=2493718331296
# pan=2493718331296
- 所谓的self,可以理解为对象自己。某个对象调用其方法时,python解释器会把这个对象作为第一个参数传递给self,所以开发者只需要传递后面的参数即可。
- self只有在类中定义实例方法的时候才有意义,在调用的时候不必传入相应的参数,而是由解释器自动地去指向
- self的名称可以更改,可以定义成其他的名字
魔术方法
- __str__方法
class Person:
def __init__(self,name,age):
self.name=name
self.age=age
pass
def __str__(self):
return '姓名: 年龄:'.format(self.name,self.age)
def eat(self):
print('吃饭')
pass
pass
pan=Person('潘小雷',20)
print(pan)
# 姓名:潘小雷 年龄:20
- __new__方法(至少有cls参数代表要实例化的类)
(1)场景:可以控制创建对象的一些属性限定,经常用来做单例模式的时候来使用
(2)__new__和__init__函数的区别:__new__类的实例化方法必须返回该实例,否则对象就创建不成功;__init__用来做数据属性的初始化工作,也可以认为是实例的构造方法,接收类的实例self并对其进行构造
(3)__new__函数要早于__init__函数执行
class Person:
def __init__(self,name,age):
print('---------------init-------------')
self.name=name
self.age=age
pass
def __str__(self):
return '姓名: 年龄:'.format(self.name,self.age)
def __new__(cls,*args,**kwargs):
print('---------------new-------------')
return object.__new__(cls) #真正创建对象实例
pass
def eat(self):
print('吃饭')
pass
pass
pan=Person('潘小雷',20)
print(pan)
# ---------------new-------------
# ---------------init-------------
# 姓名:潘小雷 年龄:20
案例
import time
class Person():
def __init__(self,name,blood):
self.name=name
self.blood=blood
def __str__(self):
return '玩家血量为'.format(self.name,self.blood)
def attack_methodA(self,enemy):
print('玩家 捅了 玩家一刀,玩家掉了10滴血'.format(self.name,enemy.name,enemy.name))
enemy.blood-=10
pass
def attack_methodB(self,enemy):
print('玩家 砍了 玩家一刀,玩家掉了15滴血'.format(self.name, enemy.name, enemy.name))
enemy.blood-=15
pass
def increase_blood(self):
print('玩家 吃药,恢复10滴血'.format(self.name))
self.blood+=10
pass
xm=Person('西门吹雪',100)
ygc=Person('叶孤城',100)
while True:
if(xm.blood<=0 or ygc.blood<=0):
break
pass
xm.attack_methodA(ygc)
print(xm)
print(ygc)
print('-------------------------------')
ygc.attack_methodB(xm)
print(xm)
print(ygc)
print('-------------------------------')
xm.increase_blood()
print(xm)
print(ygc)
print('-------------------------------')
time.sleep(1)
pass
面向对象基础(中)
析构方法
- 当一个对象被删除或者被销毁时,Python解释器也会默认调用一个方法,这个方法为__del__()方法,也称为析构方法
- 程序执行结束自动调用析构方法
- 当对象被手动销毁时也会自动调用__del__方法
- 析构函数一般用于资源回收
class Animal:
def __init__(self,name):
self.name=name
print('这是构造初始化方法')
pass
def __del__(self):
print('这是析构方法')
pass
cat=Animal('小猫')
# 这是构造初始化方法
# 这是析构方法
class Animal:
def __init__(self,name):
self.name=name
print('这是构造初始化方法')
pass
def __del__(self):
print('这是析构方法')
pass
cat=Animal('小猫')
del cat # 手动删除对象
input('程序等待中')
# 这是构造初始化方法
# 这是析构方法
# 程序等待中
继承
单继承
- 对于面向对象的继承来说,其实就是将多个类共有的方法提取到父类中,子类仅需继承父类而不必一一去实现
class Animal:
def eat(self):
print('吃')
pass
def drink(self):
print('喝')
pass
class Dog(Animal):
def wwj(self):
print('汪汪叫')
pass
pass
class Cat(Animal):
def mmj(self):
print('喵喵叫')
pass
pass
d1=Dog()
d1.eat()
c1=Cat()
c1.eat()
# 吃
# 吃
多继承
class shenxian:
def fly(self):
print('神仙都会飞')
pass
class Monkey:
def eat(self):
print('猴子喜欢吃桃')
pass
class SunWukong(shenxian,Monkey):
pass
sunWuKong=SunWukong()
sunWuKong.fly()
sunWuKong.eat()
# 神仙都会飞
# 猴子喜欢吃桃
class D(object):
def eat(self):
print('D.eat')
pass
class C(D):
def eat(self):
print('C.eat')
pass
class B(D):
pass
class A(B,C):
pass
a=A()
a.eat()
print(A.__mro__) # 可以显示类的依次继承关系
# 执行顺序:A-》B-》C(-》D)
# C.eat
# (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>)
重写父类方法
所谓重写,就是子类中,有一个和父亲相同名字的方法,在子类中的方法会覆盖掉父类中同名的方法
调用父类方法
class Dog:
def __init__(self,name,color):
self.name=name
self.color=color
pass
class keji(Dog):
def __init__(self,name,color,height,weight):
Dog.__init__(self,name,color) # 调用父类方法
# super.__init__(name,color) # 另外一种方式 super自动找到父类进而调用方法
self.height=height
self.weight=weight
pass
def __str__(self):
return '名字: 颜色: 高度: 重量:'.format(self.name,self.color,self.height,self.weight)
kejiA=keji('柯基犬','红色',30,50)
print(kejiA)
# 名字:柯基犬 颜色:红色 高度:30 重量:50
多态
- 所谓多态,定义时的类型和运行时的类型不一样,此时就成为多态(同一种行为,对于不同的子类有不同的有不同的行为表现)
- 实现多态的前提:
(1)多态必须发生在父类和子类之间
(2)子类重写父类的方法
class Person:
def say_who(self):
print('我是一个人')
pass
class Student(Person): # 子类继承父类
def say_who(self):
print('我是一个学生') # 子类重写父类方法
pass
class Teacher(Person):
def say_who(self):
print('我是一个老师')
pass
def commonInvoke(obj):
obj.say_who()
listObj=[Student(),Teacher()]
for item in listObj:
commonInvoke(item)
# 我是一个学生
# 我是一个老师
- 多态可以增加程序的灵活性,增加程序的扩展性
- 鸭子类型:只要看起来像鸭子,就是鸭子
类属性和实例属性
- 类属性:就是类对象所拥有的属性,可以被所有类对象的实例对象所共有,类对象和实例对象可以访问
- 实例属性:实例对象所拥有的属性,只能通过实例对象访问
- 类属性只能通过类对象修改
class Student:
name='潘小雷' # 属于类属性 就是student类对象所拥有的
def __init__(self,age):
self.age=age # 实例属性
pass
pass
rainy_universe=Student(19)
print('-----------通过实例对象访问类属性和实例属性------------')
print(rainy_universe.name)
print(rainy_universe.age)
print('-----------通过类对象访问类属性和实例属性--------------')
print(Student.name)
# print(Student.age) # error
# -----------通过实例对象访问类属性和实例属性------------
# 潘小雷
# 19
# -----------通过类对象访问类属性和实例属性--------------
# 潘小雷
class Student:
name='潘小雷' # 属于类属性 就是student类对象所拥有的
def __init__(self,age):
self.age=age # 实例属性
pass
pass
Student.name='雨宙' # 类属性只能通过类对象修改
rainy_universe=Student(19)
print('-----------通过实例对象访问类属性和实例属性------------')
print(rainy_universe.name)
print(rainy_universe.age)
print('-----------通过类对象访问类属性和实例属性--------------')
print(Student.name)
# print(Student.age) # error
# -----------通过实例对象访问类属性和实例属性------------
# 雨宙
# 19
# -----------通过类对象访问类属性和实例属性--------------
# 雨宙
类方法和静态方法
- 类方法:类对象所拥有的方法,需要用装饰器@classmethod来标识其为类方法,对于类方法,第一个参数必须是类对象,一般以cls作为第一个参数,类方法可以通过类对象,实例对象调用
class People:
country='China'
# 类方法,用@classmethod进行修饰
@classmethod
def get_country(cls):
return cls.country
pass
@classmethod
def change_country(cls,data):
cls.country=data
pass
pass
# 通过类对象去引用
print(People.get_country()) # China
# 通过实例对象去引用
peopleA=People()
print(peopleA.get_country()) # China
People.change_country('英国')
print(People.get_country()) # 英国
- 静态方法:类对象所拥有的方法,需要用@staticmethod来表示静态方法,静态方法不需要任何参数
- 一般情况下,不会通过实例对象访问静态方法
- 由于静态方法主要存放逻辑性的代码,本身和类以及实例对象没有交互,在静态方法中,不会涉及到类中方法和属性的操作
class People:
country='China'
@staticmethod
def getData():
return People.country # 通过类对象去引用
pass
p=People()
print(p.getData()) # China
import time
class TimeTest:
def __init__(self,hour,min,second):
self.hour=hour
self.min=min
self.second=second
@staticmethod
def showTime():
return time.strftime("%H:%M:%S",time.localtime())
pass
print(TimeTest.showTime()) # 11:23:26
- 类方法第一个参数是类对象,简称cls,进而去引用类对象的属性和方法;实例方法的第一个参数必须是self,通过这个self可以去引用类属性或实例属性,若存在相同名称的实例属性和类属性的话,实例属性的优先级最高;静态方法不需要定义额外的参数,若是要引用属性的话,则可以通过类对象或实例对象去引用
面向对象基础(下)
私有化属性
- 两个下划线开头,声明该属性为私有,不能在类的外部被使用或直接访问
- 私有化属性不能在外部直接访问,可以在类的内部随意使用
- 子类不能继承父类的私有化属性,只能继承公共的属性和行为
class Person:
def __init__(self):
self.__name='潘小雷'
pass
def __str__(self):
return '姓名:'.format(self.__name)
class Student(Person):
pass
pan=Person()
# print(pan.__name) # error 私有属性不能在外部使用
print(pan.__str__()) # 姓名:潘小雷
stu=Student()
# print(stu.__name) # error 私有属性不能被继承
class Person:
def __init__(self):
self.__name='潘小雷'
pass
def change_name(self,data):
self.__name=data
pass
def __str__<以上是关于Python编程基础的主要内容,如果未能解决你的问题,请参考以下文章