Python——面向对象
什么是类class:
具有相同方法和属性的一类事物叫做类。
什么是对象,实例:
一个拥有具体属性值和动作的具体个体。
什么是实例化:
从一个类得到一个具体对象的过程。
class Foo( object ):
def __init__( self ):
print ( 11111 )
print ( self )
name = 'haha'
lis = []
def func( self ):
pass
onj1 = Foo() #实例化一个Foo对象。
print (onj1)
实例化一个对象的时候,会发生:
1. 在内存中开辟一个对象空间。
2. 自动执行类中的__init__方法,并将这个对象空间(内存地址)传给了__init__方法的第一个未知参数self。
3. 在__init__方法中通过self给对象空间添加属性。
什么是组合:
一个类的对象作为另一个类对象的实例变量。
面向对象特点:
1. class 后首写字母必须大写
2. self为实例化对象的内存指向,每个方法默认必须有。必须要注意每一个self的内存对象指的是哪一个,还有就是在哪个方法内使用的。
基础格式:
class Foo( object ): #class + 类名称(首字母大写)(object为生成内存地址使用,py3不写也可以,py2必须写)
def __init__( self ,name,age,): #初始化,在执行序列化时,就需要执行初始化过程。
self .name = name #将对象和导入的参数进行对应。
self .age = age
def func( self ):
print ( self .name, self .age) #调用类的变量。
obj1 = Foo( 'xuan' , 22 ) #序列化一个类,并赋值给obj1这个变量中。
obj1.func() #运行obj1内的方法。
三大特点:
封装
1. 将多个相同类型的方法封装到一个类中,使其统一,
2. 将常用变量保存在类中,以供方法调用。
class Foo( object ):
name = 'xuan' #将常用变量存在类中,方便方法调用
def func( self ):
print ( self .name)
obj1 = Foo()
print (obj1.name) < / span>< / span>< / span>< / span>< / span>
成员修饰符
1. 未加下划线变量或方法
2. 加_单下划线的变量或方法
3. 加__双下划线的变量或方法
未加下划线的变量或方法。
全局可用,可在任意位置调取使用或更改。模块导入调用也可以。
class Foo( object ):
name = 'xuan' #公有
def func( self ):
print ( self .name)
obj1 = Foo()
print (obj1.name) #在类外可以正常调用
obj1.func()
加_单下划线的变量或方法。
单个下划线是一个Python命名约定,表示这个名称是供内部使用的。 它通常不由Python解释器强制执行,仅仅作为一种对程序员的提示。
以单个下划线开头的变量或方法仅供内部使用。 该约定在PEP 8中有定义。
from test import * obj1 = _Foo( 'yong' ) #在导入一个模块并使用类时,由于带有下划线,导入*的话是会报错的。
加__双下划线的变量或方法
只能在类的内部使用,既不能在类的外部调用,也不能在子类中使用。
class Obj1():
def __init__( self ):
self .__name = 'xuan'
print ( self .__name)
def pr( self ):
print ( self .__name)
foo = Obj1()
foo.pr()
# print(foo.__name) #报错。
可以使用_Foo__name 强制访问
class Foo( object ):
__name = 'xuan' #公有
def func( self ):
print ( self .__name)
obj1 = Foo()
print (obj1.name) #会报错
print (obj1._Foo__name) #可强制在外部访问
obj1.func() #只能调用内部方法,用内部方法调用
class Obj1():
def __init__( self ):
# __name = 'xuan' #这样是不行的。
self .__name = 'xuan'
def pr( self ):
print ( self .__name)
obj1 = Obj1()
obj1.pr()
继承
将一个或多个类关联到一起,当此类中没有对应的方法时,会查找父类(继承类),多个继承类则从左至右依次查找。
注意:
1. 当多继承时,一定要注意self的指向和初始方法调用点在哪里。
2. 多个类中如果有多个相同方法,可以放到基类中避免重复编写(相当于装饰器)。
3. 如果自己和父类都想调用相同属性,方法。使用super&指定类名。
class Foo( object ): #父类(基类)
name = 'xuan'
def func( self ):
print ( self .name)
class Content(Foo): #子类(派生类)
def func1( self ):
print ( self .name)
obj1 = Content()
print (obj1.name)< / span>< / span>< / span>< / span>< / span>
新式类与经典类:
Py2继承object就是新式类,默认是经典类。Py3都是新式类,默认继承object
新式类:
1. 继承object
2. 支持super
3. 多集成,广度优先(C3算法)
4. 支持mro方法
经典类:
1. 不继承object
2. 不支持super
3. 多继承,深度优先
4. 没有mro方法
继承的查找顺序:
广度优先:
Py3所有类默认。

深度优先:
1. Py2默认
2. 不查找相同的基类

mro方法:
获取类继承顺序。
import inspect print (inspect.getmro(A))
多态(鸭子模型)
一个类表现出来的多种形态
鸭子模型:
多种形态用一个类表现出来。
class Foo( object ):
def func( self ,name): #name可以是任何形态的数据类型。(任何物种)
print (name[ 2 ]) #而多种形态下,必须要有可切片功能的才能正常执行。(鸭子叫)
obj1 = Foo()
obj1.func( 'haha' )
< / span>< / span>< / span>< / span>< / span>
类变量与实例变量:
1. 类变量小于实例变量
class Foo( object ):
name = 'xuan' #类变量
def func( self ):
print ( self .name)
obj1 = Foo()
obj1.name = 'yong' #实例变量
print (Foo.name) #只输出类变量
obj1.func()
2. 在类内部的类变量在解释的时候就会执行,而内部的方法时在调用的时候再执行。
class Foo( object ):
print ( 111 ) #在python解释器解释时,就会直接运行类中的类变量。
def func( self ):
pass
class Foo( object ):
print ( 111 ) #在python解释器解释时,就会直接运行类中的类变量。
def func( self ):
pass
class Bor( object ):
print ( 222 ) #类在嵌套时也同样会运行类变量。
属性
@property
class Foo( object ):
name = 'xuan'
def __init__( self ,name):
self .name = name
@property
def func( self ):
print ( self .name)
obj1 = Foo( 'yong' )
obj1.func #无需使用()来执行,并且要求必须没有传参的情况下。
class Foo():
@property
def AAA( self ):
print ( '111' )
@AAA .setter
def AAA( self ,value):
print ( '222' )
@AAA .deleter
def AAA( self ):
print ( '333' )
f1 = Foo()
f1.AAA = 'aaa'
f1.AAA
del f1.AAA
'''
222
111
333
只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
'''
方法
方法和函数的区别:
1. 通过打印函数名确定
def func():
pass
print (func)
#
class A():
def func( self ):
pass
obj = A()
print (obj.func)
#bound method A.func of <__main__.A object at 0x00000256AD077700>
2. 通过types模块验证。
from types import FunctionType
from types import MethodType
def func():
pass
class A:
def func( self ):
pass
obj = A()
print ( isinstance (func,FunctionType)) #True
print ( isinstance (A.func,FunctionType)) #True
print ( isinstance (obj.func,FunctionType)) #False
print ( isinstance (obj.func,MethodType)) #True
3. 函数的是显示传递数据,如我们需要指明为len()函数传递一些要处理的数据。
4. 方法中的数据则是隐式传递的。
5. 函数跟对象无关
6. 方法可以操作类内部的数据
7. 方法跟对象是关联的,strip()是通过str对象来调用的。
实例方法:
定义:第一个参数必须是实例对象,该参数名一般约定为“self”,通过它来传递实例的属性和方法(也可以传类的属性和方法)
调用:只能由实例对象调用
详解:实例方法就是类的实例能够使用的方法。、
静态方法
定义:使用装饰器@staticmethod。参数随意,没有“self”和“cls”参数,但是方法体中不能使用类或实例的任何属性和方法。
调用:实例对象和类对象都可以调用、
详解:静态方法是类中的函数,不需要实例。静态方法主要是用来存放逻辑性的代码,逻辑上属于类,但是和类本身没有关系,也就是说在静态方法中,不会涉及到类中的属性和方法的操作。可以理解为,静态方法是一个独立的、单纯的函数,它仅仅托管于某个类的名称空间中,便于使用和维护。
@staticmethod
class Foo( object ):
@staticmethod
def func():
print ( 111 )
Foo.func()
类方法
定义:使用装饰器@classmethod,第一个参数必须是当前类对象,该参数名一般约定为“cls”,通过它来传递类的属性和方法。(不能传实例的属性和方法)
调用:实例对象和类对象都可以使用
详解:原则上,类方法是将类本身作为对象进行操作的方法。
classmethod
class Foo( object ):
name = 'xuan'
def __init__( self , name):
self .name = name
@classmethod
def func( cls ): # cls为类的实例化,不是变量的实例化
print ( cls .name) # cls.name 为类变量
obj1 = Foo( 'yong' )
obj1.func()
super
class Foo( object ):
def func( self ):
print ( 111 )
class Base(Foo):
def func1( self ):
super ().func()
#在运行方法时,可以同时运行Foo类中的func方法。
pass
obj1 = Base() #如果是多继承,那么就会按照查找顺序进行查找。
obj1.func1()
类中特殊方法:
__new__&__init__&__call__
class Foo( object ):
def __init__( self ,a1):
'''
称为:初始化方法
初始化使用,先有用new方法创建一个对象后,再使用init进行对象的初始化。
'''
self .a1 = a1
print ( 1 )
def __new__( cls , * args, * * kwargs):
'''
称为:构造方法
new为创建一个空对象。在实例化时,就会首先进行此方法来创建一个空对象。
:return: 返回什么,obj1就等于什么。
'''
print ( 2 )
return object .__new__( cls )
def __call__( self , * args, * * kwargs):
'''
当没有call方法时,对象加()会报错,而类中有call时,那么就会运行call方法中的内容。
:param args:
:param kwargs:
:return:
'''
print ( 3 )
obj1 = Foo( '1111' )
obj1()
iter
class Foo(object):
def __iter__(self,a1):
'''
称为:在将Foo实例化后,进行for循环时,将会执行此操作
'''
yield 1
foo = Foo()
for i in foo:
print(i)
getitem/setitem/delitem
class Foo( object ):
def __setitem__( self , key, value):
print (key)
print (value)
def __getitem__( self , item):
print (item)
def __delitem__( self , key):
print (key)
obj1 = Foo()
#和字典一样的形式。
obj1[ 1 ] = 2 #当有这样形式的对象设置时,会调用内部的setitem方法。
obj1[ 3 ] #调用内部getitem
del obj1[ 1 ] #调用内部delitem
str
class Foo( object ):
def __init__( self , name, age):
self .name = name
self .age = age
def __str__( self ):
'''
有str方法时,将会把对象以字符串形式输出。return什么,就输出什么。但如果运行方法,那么就不会有影响。
:return:
'''
return f "{self.name}:{self.age}"
user_list = [Foo( 'xuan' , 12 ), Foo( 'yong' , 23 ), Foo( 'jun' , 34 )]
for i in user_list:
print (i)
str和repr的区别
- 当单独打印对象时,会调用str方法
- 如果调用内置数据类型时(列表,元组等),将会优先调用repr方法。
class Name():
def __init__(self,username):
self.username=username
def __str__(self):
return self.username
def __repr__(self):
return self.username
class Class():
def __init__(self,name):
self.name = name
self.name_list = []
n1 = Name('he1')
n2 = Name('he2')
c1 = Class('C1')
c1.name_list.append(n1)
c1.name_list.append(n2)
for i in c1.name_list:
print(i)
print(c1.name_list)
dict
只能进行查询,不能增删改。
class Foo( object ):
def __init__( self , name, age):
self .name = name
self .age = age
obj1 = Foo( 'xuan' , 123 )
print (obj1.__dict__) #将形参和实参进行一一对应,组成字典。
#{'name': 'xuan', 'age': 123}
enter&exit
class Foo( object ):
'''
先进行enter方法中的代码,然后返回给ff,最后缩进完成时裕兴exit方法。
'''
def __enter__( self ):
self .x = 8 + 8
return self .x
def __exit__( self , exc_type, exc_val, exc_tb):
print ( 'exit' )
with Foo() as ff:
print (ff)
print (ff)
对象的加减乘除
class Foo1( object ):
def __add__( self , other):
print ( 112 )
class Foo( object ):
'''
self为obj1 ,other为obj2,返回什么val就是什么。
'''
def __add__( self , other):
return 123
obj1 = Foo()
obj2 = Foo1()
val = obj1 + obj2
print (val)
类判断:
type
class Foo( object ):
pass
class Base(Foo):
pass
obj1 = Base()
if type (obj1) = = Base: #判断对象和和类是否一致。
print ( 1 )
issubclass
class Foo( object ):
pass
class Base(Foo):
pass
class Bass():
pass
obj1 = Base()
print ( issubclass (Base,Foo)) #True
print ( issubclass (Bass,Foo)) #False
isinstance
class Foo( object ):
pass
class Base(Foo):
pass
class Bass():
pass
obj1 = Base()
print ( isinstance (obj1,Foo)) #判断对象是否是类或基类的实例
print ( isinstance (obj1,Bass)) #False
数据结构:
这里的队列和栈会在网络编程时用到。
队列:
像排队取号吃饭一样,先拿到号的肯定会先进去吃饭。
先进先出:FIFO
#队列: 先进先出
class Queue( object ):
def __init__( self ):
self .data_list = []
def push( self ,name):
self .data_list.insert( 0 ,name)
def pop( self ):
return self .data_list.pop()
obj1 = Foo()
obj1.push( '1' )
obj1.push( '2' )
obj1.push( '3' )
print (obj1.pop())
print (obj1.pop())
print (obj1.pop())
栈:
像弹夹里装子弹一样,最后进去的反而会最先被打出来。
后进先出,LIFO
#栈: 后进先出
class Stack( object ):
def __init__( self ):
self .data_list = []
def push( self ,name):
self .data_list.append(name)
def pop( self ):
return self .data_list.pop()
obj1 = Foo()
obj1.push( '1' )
obj1.push( '2' )
obj1.push( '3' )
print (obj1.pop())
print (obj1.pop())
print (obj1.pop())

浙公网安备 33010602011771号