zoukankan      html  css  js  c++  java
  • Python类中装饰器classmethod,staticmethod,property,

    @classmethod

    有的时候在类中会有一种情况,就是这个方法并不需要使用每一个对象属性
    因此 这个方法中的self参数一个完全无用的参数,使用classmethod

    class A:
        __count = 0  # 隐藏类count属性
    
        def __init__(self, name):
            self.name = name
            self.__add_count()  # 每一次实例化的时候掉
            # 用私有方法来对__count 进行累加
    
        @classmethod
        def __add_count(cls):  # 定义一个私有方法
            print(cls, A)
            A.__count += 1  # 让这个方法只能在类的内部被使用
    
        @classmethod
        def show_count(cls):  # 被classmethod 装饰去的方法,
            print(cls.__count)
            return A.__count  # 让用户可以从外部查看__count的值
    
        def show_count_self(self):  # 定义一个普通方法
            # print(self.__count)
            print(self)
            # print('_____')
            # print(self.show_count(),'fogogo')
            # return A.__count  # 让用户可以从外部查看__count的值
    
    
    # show_count 是一个查看类中属性的方法,这样的方法和某一个对象并没有直接联系        
            
    
    
    obj = A('baozi')
    print(A._A__add_count) # 
    # 执行结果
    <class '__main__.A'> <class '__main__.A'>
    <bound method A.__add_count of <class '__main__.A'>>
    
    
    

    本质上 :

    @classmethod

    一个方法不用对象属性但是使用静态属性 -- 类方法@classmethod
    某一个方法被创造出来,就是为了进行对静态变量进行操作

    @staticmehtod

    根本不涉及到对象,所以这个方法就应该被定义成 类方法(被@classmethod装饰)
    调用这个类方法,可以使用对象调用,也可以使用类调用
    但是这个方法的默认参数永远是当前类的命名空间,而不是对象的

    @staticmethod

    如果一个类中的方法不用 对象属性 也不用 静态属性 -- 静态方法@staticmethod

    那实际上这个方法就是一个普通的函数

    
    class User(object):
    
        @staticmethod
        def login(arg1, arg2):#是User类中的名字函数的名字login就是一个类中的静态方法,本质上就是一个函数
            return (arg1 + arg2)
    
    
        def show(self):
            print('---->show')
            print('---self--',self.login(1, 3))
            print('class--',User.login(123, 31))
    
    
    print(User.login(1,2)) ## 不需要实例化,当函数使用
    print(User().show())
    
    # 执行结果
    
    3
    ---->show
    ---self-- 4
    class-- 154
    
    

    一个不需要用到对象命名空间中的变量方法,就不是一个对象方法,就应该是一个普通的函数

    方法的查找的顺序:

    • 是直接在自己的空间找到类 类这个方法

    • 对象先在自己的空间找,找不到,就到类的空间

    classmethod staticmethod 使用场景说明:

    用哪一个命名空间的名字,就定义的不同的方法
    1. self 只要用self 就是普通方法,只能用对象调

    2. Classmethod 只要cls 就是类方法,可以用类,可以用对象

    3. Staticmethod 啥用不用 就是静态方法 ,可以用,可以用对象

    普通的方法 类方法 静态方法
    默认参数 self cls
    操作变量 操作对象属性 操作静态属性 既不操作对象属性,也不操作类的属性
    所属的命名空间
    调用方式 对象 类/对象 类/对象
    对应的装饰器 @classmethod @staticmethod

    @property

    把一个方法伪装成属性,

    下面例子中计算圆面积的公式

    
    class Cirecle:
        def __init__(self, r):
            self.r = r
    
        @property
        def area(self):  # 被property 装饰器 装饰的方法不能传递 除self以外参数
    
            return pi * self.r ** 2
    
        def perimeter(self):
            return self.r * pi * 2
    
    
    c1 = Cirecle(5)
    
    print(c1.area)
    # 打印执行结果
    
    78.53981633974483
    
    
    

    某一个属性需要被私有,但是有需要可以被外部查看, 这种情况,把这个属性通过方法,`property 伪装成属性

    class Person:
    
        def __init__(self, name):
            self.__name = name  # 不让外面随便修改
    
        @property
        def get_name(self):
            return self.__name
    
    
    ari = Person('arimiage')
    
    print(ari.get_name)
    # 执行结果
    
    arimiage
    

    Property 修改属性值

    • @funcname.setter
    • @funcname.deleter
    class Person:
    
        def __init__(self, name):
            self.__name = name
    
        @property
        def name(self):
            return self.__name
    
        @name.setter  # 只能传一个参数。之前必须有一个同名的方法被property装饰过
        def name(self, new_name):
            if isinstance(new_name, str):
                # if type(new_name) is str:
                self.__name = new_name
                #setattr装饰的函数名叫什么
                #那么这个函数中绝对不可以对这个,函数名同名属性进行修改( 函数名)
    
        @name.deleter
        def name(self):
            print('gogoog')
            del self.__name #这里才执行删除属性操作
    
        def get_name(self):
            return self.__name
    
        # def set_name(self,new_name):
        # if type(new_name) is str:
        # if isinstance(new_name,str):
        #     self.__name == new_name
    
        
    
    ari = Person('arimiage')
    {'_Person__name': 'arimiage'}
    # print(Person.__dict__)
    
    print(ari.get_name)
    
    ari.name = 'fgo'
    {'_Person__name': 'fgo'} #对象空间
    print(Person.__dict__)
    print(ari.__dict__)
    print(ari.name)
    
    del ari.name # 只是相当于调用被deleter装饰的方法,并不相当于删除name属性
    {} 对象空间为空
    
    # print(ari.__dict__)  # 报错
    
    
  • 相关阅读:
    Climbing Stairs 爬楼梯问题,每次可以走1或2步,爬上n层楼梯总方法 (变相fibonacci)
    Search Insert Position 查找给定元素在数组中的位置,若没有则返回应该在的位置
    Remove Duplicates from Sorted List 去除链表中重复值节点
    Populating Next Right Pointers in Each Node 设置二叉树的next节点
    Binary Tree Inorder/Preorder Traversal 返回中序和前序/遍历二叉树的元素集合
    Same Tree 比较两个二叉树是否完全相同
    Linked List Cycle 判断一个链表是否存在回路(循环)
    Reverse Integer 旋转数字
    Maximum Depth of Binary Tree 二叉树的深度
    Single Number 数组中除了某个元素出现一次,其他都出现两次,找出这个元素
  • 原文地址:https://www.cnblogs.com/lixin012007/p/10933685.html
Copyright © 2011-2022 走看看