python类中方法和属性的分类概述

作者: 阿敏其人 | 来源:发表于2018-08-10 18:01 被阅读41次

    本文出自“阿敏其人”简书技术博客,转载请注明出处。
    文/阿敏其人


    一、类的创建

    创建格式

    class 类名:
    
        def 方法1(self, 参数列表):
            pass
    

    .
    来个例子

    class Dog:
        """这是一个狗类"""
    
        def eat(self):
            print("吃香喝辣")
    
    # 创建示例
    d1 = Dog();
    

    .
    .

    类的属性和方法 初探

    在类里面可以直接定义 属性 和 方法,跟其他语言类似。

    __dir__方法

    在python里,我们可以通过 __dir__ 查看当前实例的所有的方法和属性。
    (并不是所有的实例拥有的属性和方法都是一样多的,待会会谈到)

    代码

    class Phone:
        """一个简单的类实例"""
        phoneColor = "经典黑"
    
        def f(self):
            return 'hello'
    
    
    # 实例化类
    x = Phone()
    
    # 访问类的属性和方法
    print("Phone 类的属性 phoneColor 为:%s" % x.phoneColor)
    print("Phone 类的方法 f 输出为: %s" % x.f())
    print("Phone类的对象 x 所有的属性和方法: %s" % x.__dir__())
    

    .
    输出

    Phone 类的属性 i 为:经典黑
    Phone 类的方法 f 输出为: hello
    Phone 所有的属性和方法: ['__module__', '__doc__', 'phoneColor', 'f', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
    
    Process finished with exit code 0
    

    通过dir列出的内容,我们的Phone的实例有一个 phoneColor 的属性。

    .
    .

    二、关于方法

    类的所有方法几乎必带的 self 形参

    • 类的所有的方法都必须带有一个self的形参,但是调用时不需要传值(静态方法和类方法除外)。
    • self代表类的对象,不是类!由 哪一个对象 调用的方法,方法内的 self 就是 哪一个对象的引用,在类封装的方法内部,self 就表示 当前调用方法的对象自己。(类方法除外)
    • 调用方法时,不需要传递 self 参数
    • self 这个词不是指定的关键字,换成 abcd 什么的也行,只是叫做 self 含义较好。
    class Test:
        def showAdd(self):
            print(self) # print(self)  可以打印出对象的地址
            print(self.__class__) # self.__class__ 可以指向真正类
    
    
    t = Test()
    t.showAdd()
    

    .
    输出

    <__main__.Test object at 0x108d17e80>
    <class '__main__.Test'>
    

    self.class 可以指向真正类

    .
    .

    init() 初始化方法

    • 类的初始化会调用 init() 的特殊方法(构造方法),开发时经常在定义类时重写该方法,做初始化操作。

    代码

    class Phone(object):
        """一个简单的类实例"""
    
        def __init__(self,brand,size):
            self.brand = brand
            self.size = size
    
    # 实例化类
    x = Phone("MI","5寸")
    
    # 访问类的属性和方法
    print("类对象 brand:%s" % x.brand)
    print("类对象 size : %s" % x.size)
    print("Phone类的对象对象 x 所有的属性和方法: %s" % x.__dir__())
    
    

    .

    类对象 brand:MI
    类对象 size : 5寸
    Phone 所有的属性和方法: ['brand', 'size', '__module__', '__doc__', '__init__', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
    
    Process finished with exit code 0
    

    初始化演示完毕,需要注意的是:brand和size,是Phone类的对象的属性,不是Phone类的属性。

    .
    .

    类的方法的分类: 公有方法、私有方法、静态方法和类方法

    公有方法

    公有方法:方法名前后都带有__,比如module
    定义方式:def namemethod(self)
    调用方式:对象名.公有方法


    私有方法

    私有方法私有方法:方法名只有前面带有__,比如 __testPrivate。

    定义方式:def __namemethod(self)
    调用方式:self._namemethod。注意:不能通过对象名直接调用。只能在属于对象的方法中通过self调用,或者在外部通过python的压缩规则进行调用。
    (后文会结合私有属性,附上例子)


    类方法

    类方法
    可以直接通过类名调用,也可以通过类的实例访问
    静态方法和类方法都无法访问类实例属性,能通过类访问类属于类属性。
    类方法,第一个参数必须要默认类,一般习惯用cls。类方法的形参 cls,代表类本身

    定义方式
    @classmethod
    def methodname(cls)

    常见场景
    类方法用在模拟java定义多个构造函数的情况。


    静态方法

    静态方法

    可以直接通过类名调用,也可以通过类的实例访问。
    静态方法和类方法都无法访问类实例属性,能通过类访问类属于类属性。
    静态方法对参数没有要求

    定义方式
    @staticmethod
    def methodname()

    调用方式:类名.方法名


    常见场景
    类中静态方法方法调用静态方法的情况。

    静态方法和类方法的简单对比

    1、两者都可以通过类对象或类名访问;静态方法和类方法都无法访问实例变量的,但可以通过类名访问类属性。
    2、静态方法和类方法,可以减少 创建多实例时 所创造出来的内存空间,加快运行速度。

    .
    .
    代码

    class Phone(object):
        """一个简单的类实例"""
    
        age = 18
    
        def __init__(self,brand,size):
            self.brand = brand
            self.size = size
    
        def normalMethod(self):
            print("方法  normalMethod 被调用 %s" % self)
    
        def pubTest(self):
            print("公有方法  pubTest 被调用 %s" % self)
    
        def __pubTestOther__(self):
            print("公有方法  __pubTestOther__ 被调用 %s" % self)
    
    
        def __privateTest(self):
            print("私有方法  __privateTest 被调用 %s" % self)
            pass
    
        @staticmethod
        def staticTest(): # 静态方法不需要默认的 self 或者 cls 作为形参
            print("静态方法  staticTest 被调用")
            print(Phone.age) # 静态方法需要通过 类名.属性 来访问属性
    
        @classmethod
        def classTest(cls):
            print("类方法  classTest 被调用 %s" % cls)
            print("类方法  访问类的属性 %s" % Phone.age)
    
    
    # 实例化类
    x = Phone("MI","5寸")
    
    print("Phone类的对象对象 x 所有的属性和方法: %s" % x.__dir__())
    
    print("")
    print("*"*10, "公有方法 开始", "*"*10)
    x.pubTest()
    
    print("*"*10, "公有方法 结束", "*"*10)
    
    print("")
    print("*"*10, "私有方法 开始", "*"*10)
    print("私有方法无法直接通过 类对象 或者 类名 访问")
    print("*"*10, "私有方法 结束", "*"*10)
    
    print("")
    print("*"*10, "静态方法 开始", "*"*10)
    x.staticTest()
    Phone.staticTest()
    print("*"*10, "静态方法 结束", "*"*10)
    
    print("")
    print("*"*10, "类方法 开始", "*"*10)
    x.classTest()
    Phone.classTest()
    print("*"*10, "类方法 结束", "*"*10)
    
    

    .
    .
    打印:

    Phone类的对象对象 x 所有的属性和方法: ['brand', 'size', '__module__', '__doc__', 'age', '__init__', 'normalMethod', 'pubTest', '__pubTestOther__', '_Phone__privateTest', 'staticTest', 'classTest', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
    
    ********** 公有方法 开始 **********
    公有方法  pubTest 被调用 <__main__.Phone object at 0x107aa02e8>
    ********** 公有方法 结束 **********
    
    ********** 私有方法 开始 **********
    私有方法无法直接通过 类对象 或者 类名 访问
    ********** 私有方法 结束 **********
    
    ********** 静态方法 开始 **********
    静态方法  staticTest 被调用
    18
    静态方法  staticTest 被调用
    18
    ********** 静态方法 结束 **********
    
    ********** 类方法 开始 **********
    类方法  classTest 被调用 <class '__main__.Phone'>
    类方法  访问类的属性 18
    类方法  classTest 被调用 <class '__main__.Phone'>
    类方法  访问类的属性 18
    ********** 类方法 结束 **********
    

    .
    .

    三、关于属性

    1:实例属性:

    最好在__init__(self,...)中初始化,内部调用时都需要加上self.

    2:类属性:

    __init__()外初始化
    类的实例或者直接通过类名都可以访问

    3:私有属性:

    1、单下划线开头:告诉别人这是私有属性,但是外部依然可以访问更改
    2、双下划线
    _开头:外部不可访问。无论是类名还是类实例。

    (python中没有绝对真正的私有属性)

    .
    .

    实例属性示例代码

    • 一个类的对象可以通过点语法为当前类的对象添加一个属性,但这种方式添加的属性只属于这个属于对象,是实例属性属性。

    代码

    class Dog:
        """这是一个狗类"""
    
        def eat(self):
            print("吃香喝辣")
    
    
    dog = Dog();
    
    
    print(dog.__dir__())
    dog.name = "大白"  
    print(dog.__dir__())
    
    # 通过 __dir__ 的打印对比,我们可以很明显地发现,dog.name = "大白"  执行过后,该对象多了一个 名为 name 的属性,这个属性只属于这个实例
    print(dog.name)
    
    dog2 = Dog() # dog2并没有 name 这个属性
    print(dog2.__dir__())
    

    .
    输出

    ['__module__', '__doc__', 'eat', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
    
    ['name', '__module__', '__doc__', 'eat', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
    大白
    ['__module__', '__doc__', 'eat', '__dict__', '__weakref__', '__repr__', '__hash__', '__str__', '__getattribute__', '__setattr__', '__delattr__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__init__', '__new__', '__reduce_ex__', '__reduce__', '__subclasshook__', '__init_subclass__', '__format__', '__sizeof__', '__dir__', '__class__']
    
    Process finished with exit code 0
    

    .
    .

    访问私有属性和私有方法 示例

    代码

    class PriTest(object):
        # 私有属性
        __priMem = "Jill"
        # 私有方法
        def __privateMethod(self):
            print("i ma a private metoid")
    
    
    pt = PriTest()
    # 利用python的压缩规则,我们依然可以调用到 私有方法。 但是不建议这么做。
    #私有属性和方法的处理方式:在 名称 前面加上 _类名 => _类名__名称
    pt._PriTest__privateMethod()
    print(pt._PriTest__priMem)
    

    .
    输出

    i ma a private metoid
    Jill
    
    Process finished with exit code 0
    

    .
    .
    END.
    谢谢阅读。

    相关文章

      网友评论

        本文标题:python类中方法和属性的分类概述

        本文链接:https://www.haomeiwen.com/subject/ymgkbftx.html