①思想:
面向对象 vs 面向过程 以模块化思想解决工程问题 由面向过程转换面向对象 面向对象的例子:
面向对象就好比,你去饭店吃饭,你只需说明想吃什么就可以了,没必要去了解这个菜是怎么做的;反侧就是面向过程。 常用名词
oo:面向对象 ooa:分析 ood:设计 oop:编程 ooi:实现 ooa-> ood-> ooi 类 vs 对象
类:抽象,叙述的是一个集合,侧重于共性 对象:具象,描述的是个体 类的内容:
②定义类:
class Student ( ) :
pass
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) )
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( 'cjl' , 18 )
print ( '我是{0}今年{1}岁' . format ( cjl. name, cjl. age) )
'''
我是cjl今年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( 'cjl' , 18 )
print ( cjl)
'''
我是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. age)
p = Person( )
print ( p)
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
print ( cjl)
cjl. sex = '男'
lxl = Men( )
lxl. name = 'lxl'
lxl. age = 15
lxl. school = '七中'
print ( lxl)
'''
cjl........19
lxl....七中....15
'''