吴先生不爱吃辣

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::

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__)

 

posted on 2020-04-07 11:53  吴先生不爱吃辣  阅读(154)  评论(0编辑  收藏  举报