Python随记(16)静态属性和方法, __str____repr__ __slots__的使用,

静态属性和方法

静态属性就是没有self参数的属性。
静态方法是类的特殊方法,静态方法只需要在普通方法的前边加上 @staticmethod 修饰符即可。 静态方法最大的优点是:不会绑定到实例对象上,换而言之就是节省开销。

class A:
	@staticmethod
	def static()
		print('hi')
a=A()
b=A()
a.static()  >>>hi
b.static()   >>>hi

__str__和__repr__的使用

用来返回特定的字符串

class A:
	def __str__(self)
		return 'hhh'
a=A()
print(a) >>> hhh
a  >>><__main__.A object at 0x0000018AE3A9DE50>

直接显示变量调用的不是__str__(),而是__repr__(),两者的区别是__str__()返回用户看到的字符串,而__repr__()返回程序开发者看到的字符串,也就是说__repr__()是为调试服务的。但是通常__str__()和__repr__()代码都是一样的__repr__ = __str__就行了

定制一个计时器的类案例

import time as t
class Mytimer:
    def __init__(self):
        self.prompt = '未开始计时啦'
        self.begin = 0         #为下一轮计时初始化
        self.end = 0
        self.unit=['年', '月', '天', '小时', '分钟', '秒']
    def start(self):
        self.begin=t.localtime()
        self.prompt = '请先调用stop()停止计时'
        print('计时开始')
    def stop(self):
        if not self.begin:
            print('请先调用start()')
        else:
            self.end =t.localtime()
            print('计时结束')
            self._calc()
    def _calc(self):
        self.list1=[]
        self.prompt = '运行了'
        for i in range(6):
            self.list1.append(self.end[i]-self.begin[i])
            if self.list1[i]:
                self.prompt += (str(self.list1[i]) + self.unit[i])
        print(self.prompt)
        self.begin = 0
        self.end = 0
    def __str__(self):
        return  self.prompt
    __repr__ = __str__

    

>>> a=Mytimer()
>>> a.stop()
请先调用start()
>>> a
未开始计时啦
>>> a.start()
计时开始
>>> a.stop()
计时结束
运行了6

为一个很短的代码计时都很复杂,因为你不知道处理器有多少时间用于运行这个代码?有什么在后台运行?小小的疏忽可能破坏你的百年大计,后台服务偶尔被 “唤醒” 在最后千分之一秒做一些像查收信件,连接计时通信服务器,检查应用程序更新,扫描病毒,查看是否有磁盘被插入光驱之类很有意义的事。在开始计时测试之前,把一切都关掉,断开网络的连接。再次确定一切都关上后关掉那些不断查看网络是否恢复的服务等等。
接下来是计时框架本身引入的变化因素。Python 解释器是否缓存了方法名的查找?是否缓存代码块的编译结果?正则表达式呢? 你的代码重复运行时有副作用吗?不要忘记,你的工作结果将以比秒更小的单位呈现,你的计时框架中的小错误将会带来不可挽回的结果扭曲。

就是我们不要自己写计时器框架啦。。。。。体会一下定制类就好,计时工具就用 timeit模块就好

获取对象信息

isinstance() 对于class的继承关系来说,使用type()就很不方便。我们要判断class的类型,可以使用isinstance()函数。如果继承关系是: object -> Animal -> Dog -> Husky。 h是Husky的实例对象。isinstance(h,Husky) isinstance(h,Dog) isinstance(h,objecrt)这些都返回True。。所以总是优先使用isinstance()判断类型,可以将指定类型及其子类“一网打尽”。
使用dir() 如果要获得一个对象的所有属性和方法,可以使用dir()函数,它返回一个包含字符串的list

__slots__的使用

正常情况下,当我们定义了一个class,创建了一个class的实例后,我们可以给该实例绑定任何属性和方法,这就是动态语言的灵活性。
给对象绑定一个属性 class A: pass a=A() a.hi = 'hi' a.hi >>>hi ;给对象绑定一个方法

def getname(self,name):
	print(name)
>>> from types import MethodType
>>> a.getname = MethodType(getname,a)   #对其他的实例对象是没用的
>>> a.getname('hi')
hi

为了给所有实例都绑定方法,可以给class绑定方法:A.getname = name b=A() b.getname('hi')
Python允许在定义class的时候,定义一个特殊的__slots__变量,来限制该class实例能添加的属性

class A:
	__slots__ = ('name','age')
a=A()
a.name='hi'
a.age=99
a.lalala = 88
Traceback (most recent call last):
  File "<pyshell#24>", line 1, in <module>
    a.lalala=123
AttributeError: 'A' object has no attribute 'lalala'

使用__slots__要注意,slots__定义的属性仅对当前类实例起作用,对继承的子类是不起作用的,除非在子类中也定义__slots_,这样,子类实例允许定义的属性就是自身的__slots__加上父类的__slots_。

发布了25 篇原创文章 · 获赞 0 · 访问量 298

猜你喜欢

转载自blog.csdn.net/weixin_46192930/article/details/105003854