山东网站开发制作千助网站建设
- 作者: 五速梦信息网
- 时间: 2026年03月21日 09:46
当前位置: 首页 > news >正文
山东网站开发制作,千助网站建设,网站托管套餐,wordpress主题更改首页目录 str iter getitem getattr call 小结 看到类似slots这种形如xxx的变量或者函数名就要注意#xff0c;这些在Python中是有特殊用途的。 slots我们已经知道怎么用了#xff0c;len()方法我们也知道是为了能让class作用于len()…目录 str iter getitem getattr call 小结 看到类似slots这种形如xxx的变量或者函数名就要注意这些在Python中是有特殊用途的。 slots我们已经知道怎么用了len()方法我们也知道是为了能让class作用于len()函数。 除此之外Python的class中还有许多这样有特殊用途的函数可以帮助我们定制类。 str 我们先定义一个Student类打印一个实例 class Student(object): … def init(self, name): … self.name name …print(Student(Michael)) main.Student object at 0x109afb190 打印出一堆main.Student object at 0x109afb190不好看。 怎么才能打印得好看呢只需要定义好str()方法返回一个好看的字符串就可以了 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) 这样打印出来的实例不但好看而且容易看出实例内部重要的数据。 但是细心的朋友会发现直接敲变量不用print打印出来的实例还是不好看 s Student(Michael)s main.Student object at 0x109afb310 这是因为直接显示变量调用的不是str()而是repr()两者的区别是str()返回用户看到的字符串而repr()返回程序开发者看到的字符串也就是说repr()是为调试服务的。 解决办法是再定义一个repr()。但是通常str()和repr()代码都是一样的所以有个偷懒的写法 class Student(object):def init(self, name):self.name namedef str(self):return Student object (name%s) % self.namerepr str iter 如果一个类想被用于for … in循环类似list或tuple那样就必须实现一个iter()方法该方法返回一个迭代对象然后Python的for循环就会不断调用该迭代对象的next()方法拿到循环的下一个值直到遇到StopIteration错误时退出循环。 我们以斐波那契数列为例写一个Fib类可以作用于for循环 class Fib(object):def init(self):self.a, self.b 0, 1 # 初始化两个计数器abdef 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 # 返回下一个值 现在试试把Fib实例作用于for循环 for n in Fib(): … print(n) … 1 1 2 3 5 … 46368 75025 getitem Fib实例虽然能作用于for循环看起来和list有点像但是把它当成list来使用还是不行比如取第5个元素 Fib()[5] Traceback (most recent call last):File stdin, line 1, in module TypeError: Fib object does not support indexing 现在就可以按下标访问数列的任意一项了 f Fib()f[0] 1f[1] 1f[2] 2f[3] 3f[10] 89f[100] 573147844013817084101 但是list有个神奇的切片方法 list(range(100))[5:10] [5, 6, 7, 8, 9] 对于Fib却报错。原因是getitem()传入的参数可能是一个int也可能是一个切片对象slice所以要做判断 class Fib(object):def getitem(self, n):if isinstance(n, int): # n是索引a, b 1, 1for x in range(n):a, b b, a breturn aif isinstance(n, slice): # n是切片start n.startstop n.stopif start is None:start 0a, b 1, 1L []for x in range(stop):if x start:L.append(a)a, b b, a breturn L 现在试试Fib的切片 f Fib()f[0:5] [1, 1, 2, 3, 5]f[:10] [1, 1, 2, 3, 5, 8, 13, 21, 34, 55] 但是没有对step参数作处理 f[:10:2] [1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89] 也没有对负数作处理所以要正确实现一个getitem()还是有很多工作要做的。 此外如果把对象看成dictgetitem()的参数也可能是一个可以作key的object例如str。 与之对应的是setitem()方法把对象视作list或dict来对集合赋值。最后还有一个delitem()方法用于删除某个元素。 总之通过上面的方法我们自己定义的类表现得和Python自带的list、tuple、dict没什么区别这完全归功于动态语言的“鸭子类型”不需要强制继承某个接口。 getattr 正常情况下当我们调用类的方法或属性时如果不存在就会报错。比如定义Student类 class Student(object):def init(self):self.name Michael调用name属性没问题但是调用不存在的score属性就有问题了 s Student()print(s.name) Michaelprint(s.score) Traceback (most recent call last):… AttributeError: Student object has no attribute score错误信息很清楚地告诉我们没有找到score这个attribute。 要避免这个错误除了可以加上一个score属性外Python还有另一个机制那就是写一个getattr()方法动态返回一个属性。修改如下 class Student(object):def init(self):self.name Michaeldef getattr(self, attr):if attrscore:return 99当调用不存在的属性时比如scorePython解释器会试图调用getattr(self, score)来尝试获得属性这样我们就有机会返回score的值 s Student()s.name Michaels.score 99返回函数也是完全可以的 class Student(object):def getattr(self, attr):if attrage:return lambda: 25只是调用方式要变为 s.age() 25注意只有在没有找到属性的情况下才调用getattr已有的属性比如name不会在getattr中查找。 此外注意到任意调用如s.abc都会返回None这是因为我们定义的getattr默认返回就是None。要让class只响应特定的几个属性我们就要按照约定抛出AttributeError的错误 class Student(object):def getattr(self, attr):if attrage:return lambda: 25raise AttributeError(\Student\ object has no attribute \%s\ % attr)这实际上可以把一个类的所有属性和方法调用全部动态化处理了不需要任何特殊手段。 这种完全动态调用的特性有什么实际作用呢作用就是可以针对完全动态的情况作调用。 举个例子 现在很多网站都搞REST API比如新浪微博、豆瓣啥的调用API的URL类似 http://api.server/user/friendshttp://api.server/user/timeline/list 如果要写SDK给每个URL对应的API都写一个方法那得累死而且API一旦改动SDK也要改。 利用完全动态的getattr我们可以写出一个链式调用 class Chain(object):def init(self, path):self._path pathdef getattr(self, path):return Chain(%s/%s % (self._path, path))def str(self):return self._pathrepr str 试试 Chain().status.user.timeline.list /status/user/timeline/list 这样无论API怎么变SDK都可以根据URL实现完全动态的调用而且不随API的增加而改变 还有些REST API会把参数放到URL中比如GitHub的API GET /users/:user/repos 调用时需要把:user替换为实际用户名。如果我们能写出这样的链式调用 Chain().users(michael).repos就可以非常方便地调用API了。有兴趣的童鞋可以试试写出来。 call 一个对象实例可以有自己的属性和方法当我们调用实例方法时我们用instance.method()来调用。能不能直接在实例本身上调用呢在Python中答案是肯定的。 任何类只需要定义一个call()方法就可以直接对实例进行调用。请看示例 class Student(object):def init(self, name):self.name namedef call(self):print(My name is %s. % self.name)调用方式如下 s Student(Michael)s() # self参数不要传入 My name is Michael. call()还可以定义参数。对实例进行直接调用就好比对一个函数进行调用一样所以你完全可以把对象看成函数把函数看成对象因为这两者之间本来就没啥根本的区别。 如果你把对象看成函数那么函数本身其实也可以在运行期动态创建出来因为类的实例都是运行期创建出来的这么一来我们就模糊了对象和函数的界限。 那么怎么判断一个变量是对象还是函数呢其实更多的时候我们需要判断一个对象是否能被调用能被调用的对象就是一个Callable对象比如函数和我们上面定义的带有call()的类实例 callable(Student()) Truecallable(max) Truecallable([1, 2, 3]) Falsecallable(None) Falsecallable(str) False通过callable()函数我们就可以判断一个对象是否是“可调用”对象。 小结 Python的class允许定义许多定制方法可以让我们非常方便地生成特定的类。 本节介绍的是最常用的几个定制方法还有很多可定制的方法请参考Python的官方文档。
- 上一篇: 山东网站开发公司淘宝关键词top排行榜
- 下一篇: 山东网站排名优化公司网站建设介绍ppt模板下载
相关文章
-
山东网站开发公司淘宝关键词top排行榜
山东网站开发公司淘宝关键词top排行榜
- 技术栈
- 2026年03月21日
-
山东网站建设培训网站建设用哪种语言
山东网站建设培训网站建设用哪种语言
- 技术栈
- 2026年03月21日
-
山东网站建设培训广东省广州市白云区广云路11号
山东网站建设培训广东省广州市白云区广云路11号
- 技术栈
- 2026年03月21日
-
山东网站排名优化公司网站建设介绍ppt模板下载
山东网站排名优化公司网站建设介绍ppt模板下载
- 技术栈
- 2026年03月21日
-
山东网站推广营销设计北京市中小企业公共服务平台
山东网站推广营销设计北京市中小企业公共服务平台
- 技术栈
- 2026年03月21日
-
山东网站推广有限公司wordpress请求超时
山东网站推广有限公司wordpress请求超时
- 技术栈
- 2026年03月21日






