廖大?为什么我的类是callable,而该类的对象却不是呢?
Topic source#!/usr/bin/env python3
# -*- coding: utf-8 -*-
'定制类'
__author__ = 'HZF'
import os
'__str__'
class Stu1(object):
def __init__(self,name):
self.__name = name
class Stu2(object):
def __init__(self,name):
self.__name = name
def __str__(self):
return 'Stu2 object (name:%s)'%self.name
@property
def name(self):
return self.__name
'__repr__'
class Stu3(object):
def __init__(self,name):
self.__name = name
def __str__(self):
return 'Stu3 object (name:%s)'%self.name
__repr__ = __str__
@property
def name(self):
return self.__name
'__iter__'#如果要一个类能够被用于for...in循环
class Fib(object):
def __init__(self,limit=100000):
self.__a = 0
self.__b = 1
self.__limit = limit
def __str__(self):
return '%s object (limit:%d)'%(self.__class__.__name__,self.__limit)
__repr__ = __str__
def __iter__(self):
return self
def __next__(self):
self.__a,self.__b = self.__b,self.__a+self.__b
if self.__a > self.__limit:
raise StopIteration()
return self.__a
'''
Fib实例虽然能作用于for循环,看起来和list有点像,但是,把它当成list来使用还是不行
'Fib' object does not support indexing
这时,__getitem__就有用了
'''
'__getitem__'
class Fib2(object):
def __init__(self,limit=10**100):
self.__a = 0
self.__b = 1
self.__limit = limit
def __str__(self):
return '%s object (limit:%d)'%(self.__class__.__name__,self.__limit)
__repr__ = __str__
def __iter__(self):
return self
def __next__(self):
self.__a,self.__b = self.__b,self.__a+self.__b
if self.__a > self.__limit:
raise StopIteration()
return self.__a
def __getitem__(self,n):
a,b = 1,1
for i in range(n):
a,b = b,a+b
return a
'''
现在就可以通过角标来得到对应的元素了
但是list有个神奇的方法:切片。对于Fib2却报错
原因是__getitem__()传入的参数可能是一个int,也可能是一个切片对象slice,所以要做判断:
'''
class Fib3(object):
def __init__(self):
self.__a = 0
self.__b = 1
def __str__(self):
return '%s object (limit:%d)'%(self.__class__.__name__,self.__limit)
__repr__ = __str__
def __iter__(self):
return self
def __next__(self):
self.__a,self.__b = self.__b,self.__a+self.__b
return self.__a
def __getitem__(self,n):
fib = self.__class__()
if isinstance(n,int):
for i in range(n):
next(fib)
return next(fib)
if isinstance(n,slice):
L = []
for i in range(n.stop):
num = next(fib)
if i>=n.start:
L.append(num)
return L
'__getattr__'
'''
正常情况下,当我们调用类的方法属性时,如果 不存在,就会报错找不到该方法或属性
要避免这种错误,除了加上该方法或属性,Python还有个机制__getattr__动态返回一个属性、方法
'''
class Stu4(object):
def __init__(self):
self.__name = 'HZF'
@property
def name(self):
return self.__name
def __getattr__(self,attr):
if attr=='age':
return 25
if attr=='info':
return lambda:[self.name,self.age]
'''
链式调用:利用完全动态的__getattr__
'''
class Chain(object):
def __init__(self,path='',user='HZF'):
self.path = path
self.__user = user
@property
def path(self):
return self.__path
@path.setter
def path(self,path):
if not isinstance(path,str):
raise ValueError('path must be a string!')
self.__path = path
'''
@property
def user(self):
return self.__user
@user.setter
def user(self,user):
self.__user = user
'''
def __getattr__(self,path):
if path=='user':
path = self.__user
return Chain('%s/%s'%(self.path,path),self.__user)
def __str__(self):
return self.path
__repr__ = __str__
'__call__'
'''
'''
class Stu5(object):
def __init__(self,name):
self.name = name
def __call__(self):
#print('My name is %s.'%self.name)
return 'My name is %s'%self.name
@property
def name(self):
return self.__name
@name.setter
def name(self,name):
self.__name = name
if __name__ == '__main__':
s1 = Stu1('Luce')
print(s1)
s2 = Stu2('Miao')
print(s2)
#但是再按下s2时得到的信息还是不爽
s3 = Stu3('Ming')
print(s3)
print([x for x in Fib()])
#print(Fib()[5])
print(Fib2()[10**3])
#print(Fib2()[5:10])
print(Fib3()[0:10])
s4 = Stu4()
print(s4.age)
print(s4.num)#None
print(s4.info())
p = Chain('help','Ming')
print(p.user.hello.make.user)
s5 = Stu5('Lance')
print(s5,callable(s5),callable(Stu5))
print(s5())
>>> a,b = 1,10
>>> a,b
(1, 10)
>>> a,b = b,a+b
>>> a,b
(10, 11)
>>> a,b = 1,10
>>> b,a = a+b,b
>>> a,b
(10, 11)
>>>
这样看来,
self.b, self.a = self.a + self.b, self.b
self.a, self.b = self.b, self.a + self.b
这两句达到的是一样的效果,并没有太大的区别,我猜self.b, self.a + self.b
可能是把这两项组成的元组tuple,后赋值给另一元组self.a, self.b
,实际上还是一个量赋值给另一个量,就像前面学习的return a,b
实际上返回的是一个量。
- 1
久疤_796