python-面向对象
2021/10/7 11:12:36
本文主要是介绍python-面向对象,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
①思想:
- 面向对象 vs 面向过程
- 以模块化思想解决工程问题
- 由面向过程转换面向对象
- 面向对象的例子:
- 面向对象就好比,你去饭店吃饭,你只需说明想吃什么就可以了,没必要去了解这个菜是怎么做的;反侧就是面向过程。
- 常用名词
- oo:面向对象
- ooa:分析
- ood:设计
- oop:编程
- ooi:实现
- ooa-> ood-> ooi
- 类 vs 对象
- 类:抽象,叙述的是一个集合,侧重于共性
- 对象:具象,描述的是个体
- 类的内容:
- 动作,函数
- 属性,变量
②定义类:
- 需用class关键字
- 类命名
- 遵循“大驼峰”
- 首字母大写
#定义一个类 class Student(): #定义空类时,可用pass当做占位符 pass #定义类中的函数一般需用self站位(self可替换),例如: class StudentAll(): name = 'cjl' age = 18 language = 'python' def hello(self): print("你好!") student = StudentAll() student.hello() print(student.name, student.age, student.language) #执行结果: ''' 你好! cjl 18 python '''
③self:
self
在对象的方法中表示当前对象本身,如果通过对象调用一个方法,那么该对象会自动传入到当前方法的第一个参数中self
并不是关键字,只是一个用于接受对象的普通参数,理论上可以用任何一个普通变量名代替- 方法中有
self形参
的方法成为非绑定类的方法,可以通过对象访问,没有self的是绑定类的方法,只能通过类访问 - 使用类访问绑定类的方法时,如果类方法中需要访问当前类的成员,可以通过
__class__
成员名
class Teacher(): name = "cjl" age = 18 def say(self): self.name = "aaa" self.age = "19" print("my name is {}".format(self.name)) #调用类内的成员时需要使用__class__ print("my age is {}".format(__class__.age)) def sayAgain(): print(__class__.name) print(__class__.age) print("hello") t = Teacher() t.say() #调用绑定类函数使用类名 Teacher.sayAgain() #执行结果: ''' my name is aaa my age is 18 cjl 18 hello '''
④五种下划线:
_
:用于临时或无意义变量的名称_xxx
:命名约定,说明该属性或方法仅供内部使用,但解释器不会强制执行xxx_
:避免声明的变量和关键字冲突__xxx
:用于声明属性和方法的私有化,解释权强制执行__xxx__
:Python自带的魔术方法,应避免自己声明该命名方式
⑤__init__构造函数:
- python自带的内置函数具有特殊的函数,使用双下划线包起来的【魔术方法】
- 是一个初始化的方法用来定义实例属性和初始化数据的,在创建对象的时候
自动调用,不用手动去调用
- 利用传参的机制可以让我们定义功能更加强大并且方便的类
class People(): def __init__(self,name,age): self.name = name self.age = age cjl = People('陈家霖',18) print('我是{0}今年{1}岁'.format(cjl.name, cjl.age)) #执行结果: ''' 我是陈家霖今年18岁 '''
self
指的是类实例对象本身,相当于java的this
⑥魔术方法:
__name__
:显示当前的类名,常用于确保只有单独运行该模块时,此表达式才成立,才可以进入此判断语法,执行其中的测试代码
if __name__ == '__main__': ...
__all__
:在使用from xxx import *
导入模块时,不会导入__all__=[]
外的方法,但import xxx
不受影响__str__
:在将对象转换成字符串,相当于java的toString
class People(): def __init__(self,name,age): self.name = name self.age = age def __str__(self): return '我是{0}今年{1}岁'.format(self.name, self.age) cjl = People('陈家霖',18) print(cjl) #执行结果: ''' 我是陈家霖今年18岁 '''
__new__
:优先__init__
初始化方法被调用,第一个参数默认为cls
class Person(object): def __init__(self, name, age): print('执行__init__') self.name = name self.age = age def __new__(cls, name, age): print('执行__new__') return super(Person, cls).__new__(cls) def __str__(self): return '<Person: %s(%s)>'%(self.name, self.age) cjl = Person('cjl', 18) print(cjl) #执行结果: ''' 执行__new__ 执行__init__ <Person: cjl(18)> '''
__mro__
:用于显示类的继承关系
class D(): def play(self): print("'D'类的play") class C(D): def play(self): print("'C'类的play") class B(D): pass class A(B,C): pass demo = A() demo.play() print(A.__mro__) #执行结果: ''' 'D'类的play (<class '__main__.A'>, <class '__main__.B'>, <class '__main__.C'>, <class '__main__.D'>, <class 'object'>) '''
__dict__
:用于查看类的所有属性,以字典形式显示
class People(): def __init__(self,name,age): self.name = name self.age = age cjl = People('cjl',18) print(cjl.__dict__) #执行结果: ''' {'name': 'cjl', 'age': 18} '''
⑦析构方法:
__del__
:和__init__
一样自动执行,用于释放对象实现资源回收,当一个对象调用后,自动执行清理该对象;也可使用del 对象名
手动清理
class People(): def __init__(self,name): self.name = name print("我是 %s 执行构造方法"%name) def __del__(self): print("执行析构方法,回收对象") cjl = People("cjl") print("--------使用手动清理--------") del cjl # 手动清理 print(cjl) #执行结果: ''' 我是 cjl 执行构造方法 --------使用手动清理-------- 执行析构方法,回收对象 NameError: name 'cjl' is not defined '''
⑧继承:
单继承
:一个子类继承一个父类(找亲爹)
class Person(): def __init__(self, name, age): self.name = name self.age = age def eat(self): print('吃饭...') class Men(Person): def __init__(self, name, age, height): super().__init__(name,age) self.height = height def play(self): print('玩儿...') def __str__(self): return '我是{}今年{}岁,身高{}'.format(self.name,self.age,self.height) cjl = Men('cjl',18,183) print(cjl, '\n调用父类方法:') cjl.eat() #执行结果: ''' 我是cjl今年18岁,身高183 调用父类方法: 吃饭... '''
多继承
:一个子类继承多个父类(认干爹)
class A(): def a(self): print("A:我是C类它祖先类") pass class B(A): def b(self): print("B:我是C类它父类") pass class C(B): pass num = C() num.a() num.b() print(C.__mro__) #执行结果: ''' A:我是C类它祖先类 B:我是C类它父类 (<class '__main__.C'>, <class '__main__.B'>, <class '__main__.A'>, <class 'object'>) '''
⑨重写:
- 所谓重写,就是在子类中有一个和父类一模一样的方法,即子类的方法会覆盖父类的方法
class Dog(): def __init__(self,name,color): self.name = name self.color = color def bark(self): print("父类:汪汪汪的叫...") class HaShiQi(Dog): def __str__(self): return '这一只 {0} 的狗叫 {1} '.format(self.color,self.name) def bark(self): # 重写父类方法 print("子类:嗷嗷嗷的叫...") hsq = HaShiQi('哈士奇','白色') print(hsq) hsq.bark() #执行结果: ''' 这一只 白色 的狗叫 哈士奇 子类:嗷嗷嗷的叫... '''
⑩多态:
- 多态的实现需要遵循两个条件:
- 继承、多态发生在父类和子类之间
- 重写、子类重写父类的方法
class Animals: def say_hello(self): print("我是一只小动物...") class People: def say_hello(self): print("我是人...") class Pig(Animals): def say_hello(self): print("我是可爱的小猪.") class Cat(Animals): def say_hello(self): print("我是呆萌的小猫.") class Dog(Animals): def say_hello(self): print("我是忠诚的小狗.") class Student(People): def say_hello(self): print("我是三年级的小朋友.") def commonInvoke(obj): obj.say_hello() listObj = [Pig(),Cat(),Dog(),Student()] for item in listObj: commonInvoke(item) #执行结果: ''' 我是可爱的小猪. 我是呆萌的小猫. 我是忠诚的小狗. 我是三年级的小朋友. '''
⑪类属性和实例属性:
- 类属性是可以被类对象和实例对象共同访问使用的
- 实例属性只能由实例对象所访问
class Person: age = 18 def __init__(self,name): self.name = name cjl = Person('cjl') print(cjl.name) print(Person.name) #执行结果: ''' 实例对象: 18 cjl 类对象: 18 AttributeError: type object 'Person' has no attribute 'name' '''
⑫类方法和静态方法:
- 类方法用
@classmethod
来修饰,类方法的第一个参数对象是cls
,虽然也能通过实例访问,但不推荐这样调用
class Person: people = 'cjl' @classmethod def get_name(cls): return cls.people @classmethod def change_name(cls,name): cls.people = name print('类方法调用:%s'%(Person.get_name())) p = Person() print('实例对象调用(不推荐):%s'%(p.get_name())) print('--------------修改之后----------------') Person.change_name('lxl') print(Person.get_name()) #执行结果: ''' 类方法调用:cjl 实例对象调用(不推荐):cjl --------------修改之后---------------- lxl '''
- 静态方法用
@staticmethod
来修饰,静态方法可以不带参数,使用类和实例均可调用
import time class TimeText: @staticmethod def time(): return time.strftime('%H:%M:%S',time.localtime()) print('类对象调用:',TimeText.time()) demo = TimeText() print('实例对象调用:',demo.time()) #执行结果: ''' 类对象调用: 09:44:47 实例对象调用: 09:44:47 '''
⑬私有化属性:
- 在属性前加
__
,私有化后在外部不能调用,子类不能继承
class Person: def __init__(self): self.__name = 'cjl' self.age = 18 def __str__(self): return '我是{0}今年{1}岁了'.format(self.__name, self.age) class Men(Person): def printInfo(self): # 无法继承父类的私有化属性 # print(self.name) print(self.age) p = Person() print(p) # 无法在外部访问私有化属性 # print(p.__name) men = Men() men.printInfo() #执行结果: ''' 我是cjl今年18岁了 子类继承父类: 18 '''
- 私有化方法:
- 和私有化属性一样,在方法前加
__
,私有化后在外部不能调用,子类不能继承
- 和私有化属性一样,在方法前加
⑭property属性函数:
- 使用
property
属性函数,用于调用和修改私有化属性
class Person: def __init__(self): self.__age = 18 def get_age(self): return self.__age def set_age(self,age): if age < 0: print("年龄有误") else: self.__age = age age = property(get_age,set_age) cjl = Person() cjl.age = 19 print('修改后的年龄:',cjl.age) #执行结果: ''' 修改后的年龄: 19 '''
⑮装饰器:
- 用于调用和修改私有属性,用关键字
@property
和@xxx.setter
进行装饰,推荐使用该方法
class Person: def __init__(self): self.__age = 18 @property def age(self): return self.__age @age.setter def age(self,age): if age < 0: print("年龄有误") else: self.__age = age cjl = Person() cjl.age = 19 print('修改后的年龄:',cjl.age) #执行结果: ''' 修改后的年龄:19 '''
⑯单例模式:
- 确保一个类只有一个实例的存在(类似win系统的回收站)
- 实现方式一:通过类属性保存初次创建的实例对象,如果存在就返回保存的,没有就创建新的实例对象
class DataBase(object): _instance = None def __init__(self, name, age): print(name, age) def __new__(cls, *args, **kwargs): if not cls._instance: cls._instance=super(DataBase,cls).__new__(cls) return cls._instance db1 = DataBase('cjl',18) print(id(db1)) db2 = DataBase('lxl',15) print(id(db2)) #执行结果: ''' cjl 18 2488840593520 lxl 15 2488840593520 '''
- 实现方式二:只执行一次init方法,通过类变量进行标记控制
class Demo(object): __instance = None __isinit = True def __init__(self, name, age): if Demo.__isinit: self.name = name self.age = age __isinit = False def __new__(cls, *args, **kwargs): if not cls.__instance: cls.__instance=super(Demo,cls).__new__(cls) return cls.__instance else: return cls.__instance d1 = Demo('cjl',18) print(id(d1), d1.name,d1.age) d2 = Demo('lxl',15) print(id(d2), d2.name,d2.age) #执行结果: ''' 2488816354400 cjl 18 2488816354400 lxl 15 '''
⑰动态绑定属性方法:
- 动态添加类属性、方法属性
class People: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return '{}今年{}岁了'.format(self.name,self.age) cjl = People('cjl',18) People.sex = '男' print(cjl) print("动态添加类属性:性别,",cjl.sex) #执行结果: ''' cjl今年18岁了 动态添加类属性:性别, 男 '''
- 动态绑定类方法
import types def textMothend(self): print('{}今年{}岁了,性别:{}'.format(self.name,self.age,self.sex)) @classmethod def classmethodTest(cls): print("类方法...") @staticmethod def staticmethodTest(): print("静态方法...") class People: def __init__(self,name,age): self.name = name self.age = age def __str__(self): return '{}今年{}岁了'.format(self.name,self.age) cjl = People('cjl',18) People.sex = '男' print(cjl) print("动态添加类属性:性别 -",cjl.sex) cjl.printInfo = types.MethodType(textMothend,cjl) #动态绑定方法 print("---------------动态绑定后-------------") cjl.printInfo() # 绑定类方法 People.TestMethod = classmethodTest print("通过类调用:",end='\t\t') People.TestMethod() print("通过实例对象调用:",end='\t') cjl.TestMethod() # 绑定静态方法 People.TestMethod = staticmethodTest print("通过类调用:",end='\t\t') People.TestMethod() print("通过实例对象调用:",end='\t') cjl.TestMethod() #执行结果: ''' cjl今年18岁了 动态添加类属性:性别 - 男 ---------------动态绑定后------------- cjl今年18岁了,性别:男 通过类调用: 类方法... 通过实例对象调用: 类方法... 通过类调用: 静态方法... 通过实例对象调用: 静态方法... '''
⑱__slots__:
__slots__ = ()
:后跟元组,类型是字符串- 限制实例添加的属性,括号内为空时,则不允许添加任何属性;
- 节省空间,使用后则类属性不会被存放在
__dict__
内,所以无法使用__dict__
访问全部类属性; - 继承时
子类不受影响
,但如果子类也声明该方法时,则也会继承父类的属性限制
class Person(object): # 添加属性限制 __slots__ = ('name','age','sex') def __init__(self): pass def __str__(self): return '{}........{}'.format(self.name,self.age) class Men(Person): __slots__ = ('school') def __init__(self): pass def __str__(self): return '{}....{}....{}'.format(self.name,self.school,self.age) pass cjl = Person() cjl.name = 'cjl' cjl.age = 19 # cjl.school = 'sqxy' # 未在属性限制范围内,所以报错 print(cjl) cjl.sex = '男' lxl = Men() lxl.name = 'lxl' lxl.age = 15 lxl.school = '七中' print(lxl) #执行结果: ''' cjl........19 lxl....七中....15 '''
这篇关于python-面向对象的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-14获取参数学习:Python编程入门教程
- 2024-11-14Python编程基础入门
- 2024-11-14Python编程入门指南
- 2024-11-13Python基础教程
- 2024-11-12Python编程基础指南
- 2024-11-12Python基础编程教程
- 2024-11-08Python编程基础与实践示例
- 2024-11-07Python编程基础指南
- 2024-11-06Python编程基础入门指南
- 2024-11-06怎么使用python 计算两个GPS的距离功能-icode9专业技术文章分享