面向对象

面向对象格式

定义:
class 类名:                - 定义了一个类                        
    def 函数名(self):        - 在类中编写了一个"方法"
        pass 
调用:
x1 = 类名()            - 创建了一个对象/实例化一个对象
x1.函数名()            - 通过对象调用其中一个方法

self是什么

self参数是python帮助我们传递的,调用的是哪个实例,self就指向谁

构造方法

__new__(self)构造方法

__init__(self)初始化

class Foo(object):
    def __init__(self, a1, a2):     # 初始化方法
        """
        为空对象进行数据初始化
        :param a1:
        :param a2:
        """
        self.a1 = a1
        self.a2 = a2

    def __new__(cls, *args, **kwargs): # 构造方法
        """
        创建一个空对象
        :param args:
        :param kwargs:
        :return:
        """
        return object.__new__(cls) # Python内部创建一个当前类的对象(初创时内部是空的.).
构造方法

方法和函数的区别

写在类中的函数叫做方法,写在类外面的就是函数

对象.xxx ->>> 方法

类.xxx ->>>函数

xxx ->>>函数

打印查看:

方法 ->>> method

函数 ->>>function

代码检查

from types import MethodType, FunctionType


def check(arg):
    """
    检查arg是方法还是函数?
    :param arg:
    :return:
    """
    if isinstance(arg, MethodType):
        print('arg是一个方法')
    elif isinstance(arg, FunctionType):
        print('arg是一个函数')
方法or函数

面向对象的三大特性

封装

将相关功能封装到一个类中

class FuncOne:
    def func1(self):
        pass

    def func2(self):
        pass

    def func3(self):
        pass

 

将数据封装到一个对象中

class FuncTwo:
    def __init__(self, para1, para2, para3):
        self.para1 = para1
        self.para2 = para2
        self.para3 = para3

继承

为了实现代码的复用性

class FuncThree:
    def func1(self):
        pass


class FuncFour(FuncThree):
    def func2(self):
        pass


obj = FuncFour()
obj.func1()

经典类和新式类:

python2:经典类和新式类(object)

python3:只有新式类

经典类的查找顺序:深度优先

新式类的查找顺序:C3算法(python2.3更新)

注意:super遵循的是__mro__执行顺序

多态

类的成员

累的变量

实例变量(字段)

实例变量是类中方法中的变量,调用时需要通过对象

class FuncChange:

    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2


obj = FuncChange(1,2)
print(obj.para1)

类变量(静态字段)

写在类的里面,类里的方法外面,调用时通过类名

class ST:
    lst = []

    def get_lst(self):
        self.lst.insert(0,33)
        return self.lst


class TT(ST):
    lst = [11, 22]


s1 = TT()
s2 = TT()
y1 = s1.get_lst()
print(y1)
y2 = s2.get_lst()
print(y2)
print(TT.lst)
注意点
class FuncChange:
    para_one = 123

    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2


print(FuncChange.para_one)

类的方法

实例方法

类中普通的方法,包含self,通过对象调用

class FuncWay:
    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2

    # 实例方法
    def func1(self):
        print(self.para1)

obj = FuncWay(1,2)
obj.func1()     # 实例方法调用

静态方法

@staticmethod,无需使用对象中封装的值,可以自己传参,且不需要self,通过类名执行

class FuncWay:
    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2

    # 静态方法
    @staticmethod
    def func2(para3):
        print(para3)

FuncWay.func2(1)     # 静态方法调用

类方法

@classmethod,包含cls,通过类名执行

class FuncWay:
    def __init__(self, para1, para2):
        self.para1 = para1
        self.para2 = para2

    # 类方法
    @classmethod
    def func3(cls, para4):
        print(cls, para4)

FuncWay.func3(1)     # 类方法调用

类的属性

通过方法改造而来,@property

只有一个参数self,调用时无需加括号,因此适用于无需传参且有返回值时使用

class FuncProperty:
    @property
    def func(self):
        return 123


obj = FuncProperty()
print(obj.func)

类的公有与私有

无论是类的变量,类的方法还是类的属性都有公有和私有,

公有就是在类的内外都可以调用,私有是只能在类的内部调用,私有的创建是在命名时在名字前加"__"

class Foo:
    a1 = 1
    __a2 = 2

    def __init__(self, num):
        self.num = num
        self.__salary = 1000

    def data(self):
        print(self.num+self.a1)


obj1 = Foo(666)
obj2 = Foo(999)
print(obj1.num)
print(obj1.a1)

obj1.num = 18
obj1.a1 = 99

print(obj1.num)
print(obj1.a1)

print(obj2.a1)
print(obj2.num+Foo.a1)
print(obj2.num+obj1.a1)
运行结果:
666
1
18
99
1
1000
1098
1
class Foo:
    a1 = 1
    __a2 = 2

    def __init__(self, num):
        self.num = num
        self.__salary = 100

    def data(self):
        print(self.num+self.a1)


obj = Foo(666)
print(obj.num)
print(obj.a1)
print(obj.__salary)
print(obj.__a2)
print(Foo.a1)
print(Foo.__a2)
运行结果:
 666
 1
 Error
 Error
 1
 Error
2
class Base:
    @classmethod
    def f3(cls):
        print(cls)

    def f1(self):
        print("base.f1")
        self.f3()


class Foo(Base):
    def f2(self):
        print("foo.f2")
        self.f1()


obj = Foo()
obj.f2()
运行结果:
foo.f2
base.f1
<class '__main__.Foo'>
3

 类的组合

调用其他类的成员

通过自己调self

class Base(object):

    def f1(self):
        print('调用了Base')


class Foo(object):

    def f1(self):
        print('我是Foo')
        Base.f1(self)

obj = Foo()
obj.f1()
运行结果:
我是Foo
调用了Base

super,按照继承的顺序找下一个

class Foo(object):
    def f1(self):
        super().f1()
        print('我是Foo')


class Bar(object):
    def f1(self):
        print('我是Bar')


class Info(Foo, Bar):
    pass


obj = Info()
obj.f1()
运行结果:
我是Bar
我是Foo

特殊成员

当对象.属性没有时,触发__getattr__方法

类名()->自动执行__init__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2
  def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2

obj = Foo(1,2)
print(obj.a1 + obj.a2)
运行结果: 
3

对象()->自动执行__call__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2
  def __call__(self, *args, **kwargs):
        print(11111, args, kwargs)
        return 123                              #可以有返回值

obj = Foo(1,2)
ret = obj(6, 4, 2, k1=456)
print(ret)
运行结果:
11111 (6, 4, 2) {'k1': 456}
123

对象['xx']->自动执行__getitem__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2
  def __getitem__(self, item):
        print(item)
        return 8        #有返回值

obj = Foo(1,2)
ret = obj['wo']
print(ret)
运行结果:
wo
8

对象['xx'] = xx ->自动执行__setitem__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2
  def __setitem__(self, key, value):
        print(key, value, 111111111)
                          #没有返回值
obj = Foo(1,2)
obj['k'] = "setitem"
运行结果:
k setitem 111111111

del 对象[xx] ->自动执行__delitem__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2
  def __delitem__(self, key):
        print(key)

obj = Foo(1,2)
del obj['wo']
运行结果:
wo

对象+对象 ->自动执行__add__

class Foo(object):
  def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2
  def __add__(self, other):
        return self.a1 + other.a2

obj = Foo(1,2)
obj1 = Foo(1,2)
obj2 = Foo(88,99)
ret = obj2 + obj1
print(ret)
运行结果:
90

with对象 ->自动执行__enter__/__exit__

class Foo(object):
    
    def __init__(self, a1, a2):
        self.a1 = a1
        self.a2 = a2

    def __enter__(self):
        print('1111')
        return 999

    def __exit__(self, exc_type, exc_val, exc_tb):
        print('22222')

obj = Foo(1,2)
with obj as f:
    print(f)
运行结果:
1111
999
22222
class UserInfo(object):
    pass

class Department(object):
    pass

class StarkConfig(object):

    def __init__(self,num):
        self.num = num

    def changelist(self,request):
        print(self.num,request)

    def run(self):
        self.changelist(999)

class RoleConfig(StarkConfig):

    def changelist(self,request):
        print(666,self.num)

class AdminSite(object):
    def __init__(self):
        self._registry = {}

    def register(self,k,v):
        self._registry[k] = v(k)

site = AdminSite()
site.register(UserInfo,StarkConfig)
site.register(Department,StarkConfig)
print(len(site._registry)) # 3
for k,row in site._registry.items():
    row.run()
组合

 __dict__

用字典反回形参和所传实参

class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def func(self):
        pass


obj1 = Foo('张三', 19)
obj2 = Foo('李四', 20)


print(obj1.__dict__)
print(obj2.__dict__)
运行结果:
{'name': '张三', 'age': 19}
{'name': '李四', 'age': 20}

__doc__

显示注释信息

class Foo(object):
    """
    返回此处的注释信息
    """
    def __init__(self):
        pass

    def func(self):
        pass

    def __str__(self):
        return "F1"


obj = Foo()
print(obj.__doc__)
运行结果:
返回此处的注释信息

__str__

打印对象时,显示的是__str__内的字符串,所以看到str不一定就是str,只有type检测出的str可信

class Foo(object):
    def __init__(self):
        pass

    def func(self):
        pass

    def __str__(self):
        return "F1"


obj = Foo()
print(obj, type(obj))
运行结果:
F1    <class '__main__.Foo'>

__iter__

将不可迭代对象变为可迭代对象

class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def func(self):
        pass

    def __iter__(self):
        return iter([11, 22, 33])

obj = Foo("张三", 18)
for el in obj:
    print(el)
运行结果:
11
22
33
1
class Foo(object):
    def __init__(self, name, age):
        self.name = name
        self.age = age

    def func(self):
        pass

    def __iter__(self):
        yield 11
        yield 22
        yield 33


obj = Foo("张三", 18)
for el in obj:
    print(el)
运行结果:
11
22
33
2 

issubclass,type,isinstance

issubclass

检查第一个参数是否是第二个参数的子孙类

class Base(object):  #
    pass


class Foo(Base):  #
    pass


class Bar(Foo):  #
    pass


print(issubclass(Bar, Base))
print(issubclass(Bar, Foo))
运行结果:
True
True
issubclass 

type

获取当前对象是由那个类创建的

class Foo(object):
    pass


obj = Foo()
print(obj, type(obj))  
if type(obj) == Foo:
    print('obj是Foo类型')
运行结果:
<__main__.Foo object at 0x00000000021EB9E8> 
<class '__main__.Foo'>
obj是Foo类型
type

isinstance

检查第一个参数(对象)是否是第二个参数(类及父类)的实例

class Base(object):
    pass


class Foo(Base):
    pass


class Tuu:
    pass


obj1 = Foo()
print(isinstance(obj1, Foo))
print(isinstance(obj1, Base))
print(isinstance(obj1, Tuu))
运行结果:
True
True
False
isinstance

 反射

getattr

根据字符串的形式,去对象中找成员

if hasattr(handler,val):
    func_or_val = getattr(handler,val)     # 根据字符串为参数,去模块中寻找与之同名的成员。
    if isinstance(func_or_val,FunctionType):
        func_or_val()
else:
    print(func_or_val)
from types import MethodType,FunctionType
def func(i):
    if isinstance(i, MethodType)
        print("这是方法")
    elif isinstance(i, FunctionType)
        print("这是函数")

hasattr 

根据字符串的形式,去判断对象中是否有成员

setattr 

根据字符串的形式,动态的设置一个成员到内存中

delattr 

根据字符串的形式,动态的删除一个成员(内存中)

 

class Foo(object):

    def __init__(self):
        object.__setattr__(self, 'info', {})  # 在对象中设置值的本质

    def __setattr__(self, key, value):
        self.info[key] = value

    def __getattr__(self, item):
        print(item+"123")
        return self.info[item]


obj = Foo()
obj.name = 'sb'
print(obj.name)
View Code

 

posted @ 2018-08-27 20:32  YaoSir66  阅读(152)  评论(0编辑  收藏  举报