python中的定制类

  1. __str__()

    在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法
    当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据

    	class Student(object):
    		def __init__(self, name):
    	        self.name = name
    		def __str__(self):
    	        return 'Student object (name: %s)' % self.name
    

    打印:

    	print(Student('Michael'))
    	Student object (name: Michael)
    
  2. __repr__()

    直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说,repr()是为调试服务的。

    在类中令__repr__ = __str__,那么直接显示变量也会返回 __str__里面的return 
    
  3. __iter__()

    class Fib(object):
    def init(self):
    self.a, self.b = 0, 1 # 初始化两个计数器a,b

    def __iter__(self):
        return self # 实例本身就是迭代对象,故返回自己
    
    def __next__(self):
        self.a, self.b = self.b, self.a + self.b # 计算下一个值
        if self.a > 100000: # 退出循环的条件
            raise StopIteration()
        return self.a # 返回下一个值
    

    输出

    		for n in Fib():
    	...     print(n)
    	...
    	1
    	1
    	2
    	3
    	5
    	...
    	46368
    	75025
    
  4. __getitem__()

    1.Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行,比如,Fib()[5]就会报错

    那么我们可以用__getitem__()方法

    class Fib(object):
        def __getitem__(self, n):
            a, b = 1, 1
            for x in range(n):
                a, b = b, a + b
            return a
    

    输出:

    >>>f = Fib()
    >>>f[0]
    1
    >>>f[1]
    1
    >>> f[2]
    2
    >>> f[3]
    3
    >>> f[10]
    89
    >>> f[100]
    573147844013817084101
    

    2.但list有个神奇的切片方法而Fib却会报错

    原因是__getitem__()传入的参数可能是一个int,也可能是一个切片对象slice,所以要做判断:

    class Fib(object):
    def __getitem__(self, n):
        if isinstance(n, int): # n是索引
            a, b = 1, 1
            for x in range(n):
                a, b = b, a + b
            return a
        if isinstance(n, slice): # n是切片
            start = n.start
            stop = n.stop
            if start is None:
                start = 0
            a, b = 1, 1
            L = []
            for x in range(stop):
                if x >= start:
                    L.append(a)
                a, b = b, a + b
            return L
    

    输出:

    >>> f = Fib()
    >>> f[0:5]
    [1, 1, 2, 3, 5]
    >>> f[:10]
    [1, 1, 2, 3, 5, 8, 13, 21, 34, 55]
    
  5. __getattr__()

    当我们调用class类中没有出现的属性,就会报错,为了避免,我们写一个__getattr__()方法,动态返回一个属性

    class Student(object):	
    
    	def __init__(self):
     		self.name = 'Michael'	
     		
    	def __getattr__(self, attr):
        if attr=='score':
            return 99
    
    	s = Student()
    	>>> s.name
    	'Michael'
    	>>> s.score
    	99
    

    该方法也可以返回函数,注意的是:只有在没有找到属性的情况下,才调用该函数。如果调用其他没有定义的属性,则会返回None

  6. __call__()

    当我们调用实例方法时,我们用instance.method()来调用。那么能不能直接在实列本身上调用呢?那么就用到了__call__()

     class Student(object):
     	def __init__(self, name):
         	self.name = name
    
     	def __call__(self):
         	print('My name is %s.' % self.name)
    

    输出

     >>> s = Student('Michael')
     >>> s() # self参数不要传入
     My name is Michael.
    

    这样我们就可以把对象看成函数,那么怎么判断一个变量是对象还是函数呢?
    那么我们通过一个callable()函数,能被调用的对象就是一个callable对象

     >>> callable(Student())
     True
     >>> callable(max)
     True
     >>> callable([1, 2, 3])
     False
     >>> callable(None)
     False
     >>> callable('str')
     False
    

    我的理解是不能被调用的对象就不是一个callable对象,而被认为是一个对象,而可以被调用的对象可以被认为就是一个函数。
    这是区分对象跟函数的标准

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Python定制是指可以通过特殊的函数来定制的行为,使其表现得像内置型一样。以下是一些常用的特殊函数: 1. `__str__(self)`:用于将对象转换为字符串,方便打印和输出。 2. `__repr__(self)`:用于将对象转换为供解释器读取的形式,通常用于调试。 3. `__len__(self)`:用于返回对象的长度,可以用于自定义容器型。 4. `__getitem__(self, key)`:用于获取对象的某个元素,可以用于自定义容器型。 5. `__setitem__(self, key, value)`:用于设置对象的某个元素,可以用于自定义容器型。 6. `__getattr__(self, name)`:用于获取对象的某个属性,可以用于实现“虚拟属性”。 下面是一个例子,演示了如何通过特殊函数来定制一个: ```python class MyList: def __init__(self, *args): self.data = list(args) def __str__(self): return str(self.data) def __repr__(self): return 'MyList(' + ', '.join(map(repr, self.data)) + ')' def __len__(self): return len(self.data) def __getitem__(self, index): return self.data[index] def __setitem__(self, index, value): self.data[index] = value def __getattr__(self, name): if name == 'reverse': return self.data[::-1] else: raise AttributeError('no such attribute') ``` 上面的代码定义了一个名为`MyList`的,它可以像内置的`list`一样使用。我们可以创建一个`MyList`对象,并对其进行操作: ```python >>> a = MyList(1, 2, 3) >>> print(a) [1, 2, 3] >>> a[1] = 4 >>> print(a) [1, 4, 3] >>> print(len(a)) 3 >>> print(repr(a)) MyList(1, 4, 3) >>> print(a.reverse) [3, 4, 1] >>> print(a.sort) AttributeError: no such attribute ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值