本文主要是介绍python-面向对象,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
①思想:
面向对象 vs 面向过程 以模块化思想解决工程问题 由面向过程转换面向对象 面向对象的例子:
面向对象就好比,你去饭店吃饭,你只需说明想吃什么就可以了,没必要去了解这个菜是怎么做的;反侧就是面向过程。 常用名词
oo:面向对象 ooa:分析 ood:设计 oop:编程 ooi:实现 ooa-> ood-> ooi 类 vs 对象
类:抽象,叙述的是一个集合,侧重于共性 对象:具象,描述的是个体 类的内容:
②定义类:
#定义一个类
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)>
'''
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-面向对象的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!