zoukankan      html  css  js  c++  java
  • 面对对象的属性和方法

    1,类的私用属性和私用方法

    类中私用属性和私用方法的使的使用是加双划线

     

    class A:
        __N = 0  # 类的数据属性就应该是共享的,但是语法上是可以把类的数据属性设置成私有的如__N,会变形为_A__N
        def __init__(self):
            self.__X = 10  # 变形为self._A__X
        def __foo(self):  # 变形为_A__foo
            print('from A')
        def bar(self):
            self.__foo()  # 只有在类内部才可以通过__foo的形式访问到.
    

     这样做的目的是让属性和方法不轻易的在类的外部访问,通过A._A__N 可以访问类属性。

    2,类方法、静态方法

    类方法是使用@classmethod来实现,作用是类方法只能访问类变量,不能访问实例变量。

    静态方法使用@staticmethod来实现,作用是静态方法不能访问实例变量和类变量。

    3,属性方法

    属性方法是通过@property来实现的,作用是把一个方法变成静态的属性。调用的时候跟调用属性一样,不需要加()

    如果需要修改属性方法进行赋值的话要重新写一个方法使用@属性方法名.setter装饰器再装饰一下。就可以对这个属性进行赋值了

    删除这个方法重写一个方法使用@属性方法名.deleter,使用deleter 删除

    4,反射

    Python面对对象的反射是通过字符串的形式来操作对象的相关属性。

    hasattr(obj,‘attr’)检测实例对象中是否包含某属性

    getattr(obj,‘attr’)获取实例对象中的属性

    setattr(obj,’attr‘,’value‘)设置对象中的属性值

    deleattr(obj,’arrt‘) 删除实例对象中的属性值

    #也可以检测当前文件中有没有某个方法和属性

    def func():
        print('s1')
    
    
    class Person(object):
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
    
    name = "test"
    import sys
    this_module = sys.modules[__name__]  # __name__ 会动态的代表当前模块名
    print(hasattr(this_module, 'func'))
    print(hasattr(this_module, 'name'))
    print(getattr(this_module, 'Person'))
    p = getattr(this_module, 'Person')
    p("zzzz", 22)
    

     5,类的双下划线

    __len__,使用len(obj)的使用会触发这个方法

    __hash__,使用hash(obj)的时候会触发到这个方法

    __eq__,在比较两个对象的值是否相等的时候触发

    class A:
        def __init__(self):
            self.a = 1
            self.b = 2
    
        def __eq__(self, obj):
            print("call eq method.")
            print(obj)
            if self.a == obj.a and self.b == obj.b:
                return True
    

     item系列:

      作用:是把一个对象变成dict,可以像dict一样增删改查

    class Brand:
        def __init__(self,name):
            self.name=name
        def __getitem__(self, item):
            print("获取KEY",item)
            print(self.__dict__[item])
        def __setitem__(self, key, value):
            print("设置一个key...",key)
            self.__dict__[key]=value
        def __delitem__(self, key):
            print('del obj[key]时,我执行')
            self.__dict__.pop(key)
        def __delattr__(self, item):
            print('del obj.key时,我执行')
            self.__dict__.pop(item)
    b=Brand('小猿圈')
    b["slogan"] = "自学编程谁不爱小猿圈"
    b["website"] = "apeland.cn"
    del b["website"]
    b['name']='小猿圈Apeland'
    b["name"]  # 获取KEY
    print(b.__dict__)
    

     __str__和__repr__

      __str__是print(obj)的时候被触发

      __repr__是交互式解释器中调用被触发

      没有__str__方法是将会使用__repr方法,这个两个方法的返回值都必须是字符串。

    __del__,当对象在内存中被释放时,自动被触发,如del obj

    __new__,执行__init__方法之前需要先执行父类的__new__方法(如果本类中无__new__方法时),所以说__init__方法是__new__方法调用出来的

        class Person(object):
            def __init__(self,name):
                self.name = name
                print("--init ....")
            def __new__(cls, *args, **kwargs):
                """
                cls  : 代表Person这个类本身
                :param args:
                :param kwargs:
                :return:
                """
                print("--in new: ",cls,*args,**kwargs)
                return object.__new__(cls)  # 调用父类的__new__方法,必须这么干 ,要不然__init__方法就不会执行了
        p = Person("Alex")
        print(p.name)
        print(Person)
    

      应用场景,可以使用__new__方法实现单例模式,因为每次实例化执行__init__前都会执行__new__方法,所以用父类的__new__实例化一个对象保存到一个类变量中,当已经实例化时就不在进行实例化了。

    class Printer(object):
        __instance = None # 用来存唯一的一个实例
        __tasks = []
        def __init__(self,task):
            self.__tasks.append(task)
            print("added a new task in queue..",task)
        def __new__(cls, *args, **kwargs):
            if cls.__instance is None: # 代表之前还没被实例化过
                obj = object.__new__(cls)
                cls.__instance = obj  # 把第一次实例化的对象 存下来,以后每次实例化都用这个第一次的对象
            return cls.__instance  # 下一次实例化时,就返回第一次实例化的对象
        def jobs(self):
            return self.__tasks
    job = Printer("job1 word")
    job2 = Printer("job2 png")
    job3 = Printer("job3 excel")
    print(id(job),id(jo
    

     __call__,当执行对象()或者类()()时被触发

     __dict__,是用来存储对象属性的一个字典,键为属性名,值为属性名的值,如果是类属性则为空。

    class Student(object):
        country = "china"  # 类属性不会放到__dict__中
    
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __str__(self):
            print("我是str")
            return "Student(%s,%d)" % (self.name, self.age)
    
    
    s1 = Student("JACK", 29)
    print(s1.__dict__)
    print(s1.__dict__["name"])  # JACK
    print(Student.__dict__)
    人生苦短,我用cnblog
  • 相关阅读:
    tomcat与resin的比较
    Linux Resin 安装配置
    [BZOJ3456]城市规划
    ZJOI 2017 仙人掌
    「LibreOJ NOI Round #1」动态几何问题
    [SDOI2015]约数个数和
    codeforce 940F
    codeforce 940F
    codeforce 940E
    [NOI2009]植物大战僵尸
  • 原文地址:https://www.cnblogs.com/wuzhibinsuib/p/12652488.html
Copyright © 2011-2022 走看看