ICode9

精准搜索请尝试: 精确搜索
首页 > 编程语言> 文章详细

Python 面向对象

2022-01-26 22:02:25  阅读:191  来源: 互联网

标签:__ name Python self 面向对象 print Foo def


Python 面向对象

1.成员共分三类

1.1 变量

1.1.1 实例变量与类变量
  • class Foo:
        # 类变量(静态字段)
        country="中国"# 每个对象中的值都相同。
        # 方法
        def __init__(self,name):
            self.name=name     # 实例变量,字段
    
        # 方法
        def func(self):
            print(self.country)
            
            print(Foo.country)# 推荐使用
    
    obj1=Foo('章北海')
    obj2=Foo('泰勒')
    print(obj1.name,obj1.country,Foo.country)# obj1.country 没有设置,默认取类的值
    obj2.country='美国'
    # 类变量,可以通过类直接访问
    print(obj2.name,obj2.country,Foo.country)
    
  • 准则:

    • 实例变量(字段)访问时,使用对象访问,即obj.name
    • 类变量(静态字段)访问时,使用类方法,即Foo.country,实在不方便时,才使用对象。
  • 类变量的是使用场景:当所有对象中有共同的字段时,且要改都改要删都删,可以将实例变量(字段)提取到类变量(静态字段)。

1.1.2 私有变量
  • 私有变量也分为两种,即私有类变量私有实例变量

  • class Foo:
        __country="中国"
        def __init__(self,name):
            self.__name=name #私有实例变量,字段
            self.age=123
    
        def func(self):
            print(self.__name)
            print(Foo.__country)
    
    obj=Foo('程心')
    # print(obj.__name) # 报错: AttributeError:'Foo' object has no attribute '__name'
    # print(Foo.__country)
    obj.func()
    
  • 私有的成员变量在 Python 中使用较少。特点是外部无法访问。特殊写法亦可获取到。一般不用。

1.2 方法

  • 分类
    • 实例方法
    • 静态方法
    • 类方法
  • 私有方法
    • 私有实例方法
    • 私有静态方法
    • 私有类方法
1.2.1 实例方法
  • 函数中必须包含self,
  • 一般通过对象调用
1.2.2静态方法
  • 编写时:

    • 方法上写上@staticmethod
    • 参数可有可无
  • 调用时:

    • 类.方法名()
    • 对象.方法名() # 不推荐使用此种方法
  • 使用场景:静态方法无需使用对象中封装的值,那么就可以使用静态方法。

  • class Foo:
        def __init__(self,name):
            self.name=name
    
        # 实例方法
        def func(self):
            print(self.name)
    
        @staticmethod
        def display():
            print(666)
    
    obj=Foo("逻辑")
    Foo.display()# 一般使用类调用
    
1.2.3 类方法
  • # -*- coding: utf-8 -*-
    '''
    @Time    : 2022/1/23 13:18
    @Author  : ziqingbaojian
    @File    : 03.方法.py
    '''
    class Foo:
        def __init__(self,name):
            self.name=name
    
        # 实例方法
        def func(self):
            print(self.name)
        
        # 静态方法
        @staticmethod
        def display():
            print(666)
    
        # 类方法
        @classmethod
        def show(cls,x1,x2):
            print(cls,x1,x2)
    
    # obj=Foo("逻辑")
    # Foo.display()# 一般使用类调用
    
    Foo.show(1,8)
    
    • 补充:self代值对象,cls代指类。
  • 定义时:

    • 方法上写上:@classmethod
    • 至少包含一个cls参数
  • 执行时:

    • 类名.方法名;默认会讲话当前类传值参数中
  • 使用场景:

    • 如果在方法中会使用到当前类,那么就可以使用类方法。单利模式可能会使用到对应的类方法。
  • 类方法与静态方法特别相似。调用时无需实例化。

1.2.4 私有方法的使用
# -*- coding: utf-8 -*-
'''
@Time    : 2022/1/23 13:18
@Author  : ziqingbaojian
@File    : 03.方法.py
'''
class Foo:
    def __init__(self,name):
        self.name=name

    # 实例方法
    def func(self):
        print(self.name)

    def __f1(self,args):
        print("私有方法")
    # 静态方法
    @staticmethod
    def __display():
        print("私有静态方法")
    @staticmethod
    def get_display():
        Foo.__display()
    # 类方法
    @classmethod
    def show(cls,x1,x2):
        print(cls,x1,x2)

# obj=Foo("逻辑")
# Foo.display()# 一般使用类调用

Foo.get_display()

1.3 属性

class Foo:

    @property
    def start(self):
        return 1
    @property
    def end(self):
        return 2

obj=Foo()
print(obj.start)
print(obj.end)

将方法改造为属性,即调用方法时通常不使用()进行调用。

  • 编写时:
    • 方法上方写上@property
    • 方法参数只有一个self
  • 调用时:
    • 无序加括号,使用 对象.方法
  • 应用场景:
    • 对于简单的方法,当无需传参,且有返回值时,可以使用@property
  • 属性也具有共有和私之分。与变量和方法类似

注意:类中私有的成员,在继承的子类中依旧不能被使用。

2.组合(建模)

2.1 对象的嵌套

# -*- coding: utf-8 -*-
'''
@Time    : 2022/1/23 14:02
@Author  : ziqingbaojian
@File    : 04.组合建模.py
'''

class School:
    def __init__(self,name,addres):
        self.name=name
        self.addres=addres

obj1=School("亚洲舰队",'自然选择号')
obj2=School("亚洲舰队",'蓝色空间号')


class Teacher:
    def __init__(self,name,age,salary):
        self.name=name
        self.age=age
        self.__salary=salary
        self.school=None
t1=Teacher("章北海",30,10000)
t2=Teacher("褚岩",20,30000)
t1.school=obj1
t2.school=obj2
# 查看舰长所在的飞船,嵌套查看
print(t1.school.name)
print(t1.school.addres)

2.2 主动调用其他类的成员

class Base:
    def f1(self):
        print("5个功能")


class Foo(object):
    def f1(self):
        Base.f1(self)
        print("3个功能功能")
        
  • 通过类名.实例方法()需要进行手动传参,传入self.

  • obj=Base()
    Base.f1(obj)# 手动传参
    

2.3 继承调用

class Base:
    def f1(self):
        print("5个功能")


class Foo:
    def f1(self):
        super().f1()
        print("3个功能")

class Info(Foo,Base):
    pass

obj=Info()
obj.f1()
# 正确执行

# obj=Foo()
# obj.f1()报错,因为类中的 super() 表示的是当前继承顺序的下一个。并不是单单的只当前类的父类
  • super() 表示的是当前继承顺序的下一个。并不是单单的只当前类的父类

3.特殊成员

3.1 常见的双下滑线方法

# -*- coding: utf-8 -*-
'''
@Time    : 2022/1/23 20:41
@Author  : ziqingbaojian
@File    : 06.特殊成员.py
'''
class Foo:
    # 初始化方法  类名()自动执行
    def __init__(self,name,age):
        print("对象初始化开始")
        self.name=name
        self.age=age
    # 对象() 自动执行
    def __call__(self, *args, **kwargs):
        print(args,kwargs)

    # 对象[xxx]自动执行
    def __getitem__(self, item):
        print(item)
        return 1

    # 对象[xxx]=11自动执行
    def __setitem__(self, key, value):
        print(key,value)
        # 本方法没返回值

    def __delitem__(self, key):
        print(1)

    # 实现对象加对象的运算
    def __add__(self, other):
        return self.age+other.age


    def __enter__(self):
        print("可以使用 with 上下文管理,返回值被 as 后面的值接收")
        return 123

    def __exit__(self, exc_type, exc_val, exc_tb):
        print(456)

obj1=Foo("啊哈",20)
obj1(1,23,3,k1="12")
res=obj1['123']
print(res)
obj1['k1']="v1"
obj1.__delitem__('123')
list
with obj1 as f:
    print(f)
    print("执行中")

image-20220123210008557

image-20220123202514799

3.2 构造方法

class Foo:
    def __init__(self,name):
        self.name=name
        print(2)
    def __new__(cls, *args, **kwargs):
        '''
        返回一个空的对象的供 init 进行初始化赋值
        :param args:
        :param kwargs:
        '''
        print(1)
        return object.__new__(cls)

obj=Foo('0')

image-20220123203842467

说明:

__init__一般称做初始化方法,__new__是真正创建对象的方法。是两个方法组成了类似与其他语言中的构造方法。

3.3 常见特殊方法的使用

  1. __dict__方法
  • class Foo:
        def __init__(self,name,age):
            self.name=name
            self.age=age
    
    obj=Foo('章北海','230')
    print(obj.__dict__)#将实例变量以字典的形式返回
    
  • image-20220123211055754

  • 补充:

    • image-20220123211850447
    • 类.__dict__,会返回包括函数在内的成员信息,使用较少。
  1. __str__方法
  • class Foo:
        def __init__(self,name,age):
            self.name=name
            self.age=age
        def __str__(self):
            return "打印对象我就执行"
    obj=Foo('章北海','230')
    print(obj)
    
  • image-20220123211259108

  • 类似与 Java中的toString()方法。

  • 补充__repr__方法

    • image-20220123211520197
    • __str__内部调用了__repr__。当类中没有__str__,但是有__repr__,打印对象时 就会执行。一般使用__str__方法较多

4.类的约束

4.1 主动抛出异常

class Foo:
    def send(self):
        # 如果抛出异常,则子类如果要调用则必须重写该方法
        raise NotImplemented(".send() must be overrideen")
    def func(self):
        print("正常执行")
class Bar(Foo):
    pass
obj=Bar()
obj.func()
obj.send()

image-20220126204449752

image-20220126204644594

4.2 抽象类和抽象方法

  • 补充:

    • Python 语言中不包含接口的数据类型,但是包含抽象类,和抽象方法。
    • Java 中包含抽象类和抽象方法,且接口中的方法必须是抽象方法。
  • from abc import ABCMeta,abstractmethod
    
    
    class Foo(metaclass=ABCMeta):
    
        def func(self):
            print(123)
    
        @abstractmethod
        def send(self):
            pass
    
    
    class Bar(Foo):
        def send(self):
            print("Hello world")
    obj= Bar()
    obj.send()
    
  • image-20220126210226974

  • 说明:在 Python 语言中一般会使用第一种方式NotImplemented异常进行处理,而不定义相关的抽象类,抽象类与抽象方法不常用。

5.多继承的补充

  • 默认:先找左边的再找右面的父类。
class A(object):
    pass

class B(object):
    def f1(self):
        print("B.f1")

class C(A,B):
    pass

obj=C()
obj.f1()

5.1 经典类和新式类

  • python2.2

    • 经典类:
    • 新式类:如果自己或自己的前辈只要有人继承 object,那么此类就是新式类。
  • python3 中全部都是新式类。

  • 区别:查找流程不同。

    • 经典类:一条到走到黑;深度优先
    • 新式类:采用 C3 算法。
  • 补充:

    查看继承关系。

    # 语法:类.__mro__
    print(E.__mro__)
    

    image-20220126212700559

    • 注意事项:super是遵循__mro__执行顺序。
    • Python2 中不包含__mro__方法。

5.2 C3 算法

image-20220126214450397

  • 简单新式类(记忆),复杂的时候使用C3算法。
    • image-20220126214315246

标签:__,name,Python,self,面向对象,print,Foo,def
来源: https://www.cnblogs.com/Blogwj123/p/15848245.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有