6.4, custom class

__str__

 

 

Direct call display is not a variable __str__(), but __repr__()the difference between the two is __str__()the returned string the user sees, and __repr__()returns the string program developers to see, that is, __repr__()for debugging services.

The solution is to define a second __repr__(). But usually __str__(), and __repr__()the code is the same

 __repr__=__str__

 

 __iter__

If you want to be a class for for ... inthe cycle, similar to that list or tuple, it must implement a __iter__()method that returns an iterator object, and then, Python for loop iteration will continue to call the object's __next__()method to get the next cycle of value until it encounters StopIterationan error exit the loop.

__getitem__

To remove the above list behaves like elements according to the following standard, need to implement __getitem__()the method:

 

 Not sliced

 

 

 I did not do processing step, and no negative processing

__getattr__

 

 

 def __getattr__(self,attr)

Note that only in the absence of property found only calls __getattr__, existing attributes, such as namenot in the __getattr__lookup.

Any such calls s.abcwill be returned None, it is because we defined __getattr__the default is returned None. Let the class responds only to a few specific attributes, we must follow the convention, throw AttributeErrorthe error:

 

class Student(object):
    def __init__(self):
        self.name='liuqi'
    def __getattr__(self,attr):
        if attr=='age':
            return lambda:25
        raise AttributeError('\'Student\' object has no attribute \'%s\'' % attr)

 

 

 

__call__

 

An object instance can have its own attributes and methods, when we call an instance method, we used instance.method()to call. You can not call it directly on the instance itself? In Python, the answer is yes.

 

Any class, only need to define a __call__()method, you can for instance be called directly

 

 How to determine whether a variable is an object or function? In fact, more often, we need to determine whether an object can be called, the object can be called is a Callabletarget , such as with the above-defined functions and our __call__()class instance:

 

 

 

 

 

class Chain(object):
    def __init__(self, path=''):
       self.__path = path

   def __getattr__(self, path):
       return Chain('%s/%s' % (self.__path, path))

   def __call__(self, path):
       return Chain('%s/%s' % (self.__path, path))

   def __str__(self):
       return self.__path

   __repr__ = __str__

   print(Chain().users('michael').repos) # /users/michael/repos

 

Step 1:
Chain()  # 实例化
Step 2:
Chain().users
# 由于没有给实例传入初始化对应属性的具体信息,从而自动调用__getattr__()函数,从而有:
Chain().users = Chain('\users') # 这是重建实例
Step 3:
Chain().users('michael')
Chain().users('michael') = Chain('\users')('michael') # 这是对实例直接调用,相当于调用普通函数一样
# 关键就在这步,上面的朋友没有说明晰(并不是说你们不懂),这一步返回的是Chain('\users\michael'),再一次重建实例,覆盖掉Chain('\users'),
#记 renew = Chain('\users\michael'), 此时新实例的属性renew.__path = \users\michael;
Step 4:
Chain().users('michael').repos
# 这一步是查询renew实例的属性repos,由于没有这一属性,就会执行__getattr__()函数,再一次返回新的实例Chain('\users\michael\repos')并且覆盖点之前的实例,
# 这里记 trinew =Chain('\users\michael\repos'),不要忘了,一单定义了一个新的实例,就会执行__init__方法;
Step 5:
print(Chain().users('michael').repos) = print(trinew)  #由于我们定义了__str__()方法,那么打印的时候就会调用此方法,据此方法的定义,打印回来的是trinew的__path属#性,即——\users\michael\repos  。至此,我们也把所有定义的有特殊用的方法都用上了,完毕。

 

Guess you like

Origin www.cnblogs.com/soberkkk/p/12637224.html