time模块、装饰器、类的装饰器、类装饰器

python  time模块

  导入模块: import time    #time模块是python中最基本的模块之一

  输出时间戳:time.time()    #可以用变量接收,要打印出来要用print(),如 a = time.time(),print(a)

                     输出为:1516330026.4591534(1970年1月1日00:00:00后经过的浮点秒数)

  时间元组: time.localtime()  #可以用变量接收,用print()打印,默认是当前的时间;也可以传入一个时间戳,

                  如:time.localtime(1316331844.899376),它将返回时间戳对应的时间元组。

                 返回值:time.struct_time(tm_year=2011, tm_mon=9, tm_mday=18, tm_hour=15,

                     tm_min=44,tm_sec=4, tm_wday=6, tm_yday=261, tm_isdst=0)

  上面的红字部分是一个时间元组,那么时间元组的含义是什么呢?返回元组的内容如下:

时间元组返回值分析
索引 属性(attribute) 值(value)
0 tm_year(年) 2018
1 tm_mon(月) 1~12
2 tm_mday(日) 1~31
3 tm_hour(时) 0~23
4 tm_min(分) 0~59
5 tm_sec(秒) 0~60
6 tm_wday(星期几) 0~6
7 tm_yday(一年中的第几天) 1~366
8 tm_isdst(是否为夏令时) 0,1,-1(-1:夏令时)

  我们经常需要格式化输出时间,那么如何才能做到呢?time模块提供了非常方便的函数供可以调用,首先我们先了解

一些需要认识的格式化符号:

python时间格式化符号
%y 两位数的年份表示(00-99)
%Y 四位数的年份表示(000-9999)
%m 月份(01-12)
%d 月内中的一天(0-31)
%H 24小时制小时数(0-23)
 %I  12小时制小时数(01-12)
 %M  分钟数(00=59)
 %S  秒(00-59)
 %a  本地简化星期名称
 %A  本地完整星期名称
 %b  本地简化的月份名称
 %B  本地完整的月份名称
 %c  本地相应的日期表示和时间表示
%j   年内的一天(001-366)
 %p 本地A.M.或P.M.的等价符 
%U   一年中的星期数(00-53)星期天为星期的开始
 %w 星期(0-6),星期天为星期的开始 
%W   一年中的星期数(00-53)星期一为星期的开始
 %x  本地相应的日期表示
 %X  本地相应的时间表示
 %Z  当前时区的名称
 %%  %号本身

 

   time模块主要要熟悉time.time( )、time.localtime([secs])、time.asctime([tupletime])、time.strftime(fmt[,tupletime])

           time.strptime(str,fmt='%a %b %d %H:%M:%S %Y')、time.mktime(tupletime)、time.sleep()

  前两个我们已经熟悉了,下面介绍其他五个:

  time.asctime([tupletime])  :接受时间元组并返回一个可读的形式为"Fri Jan 19 13:37:39 2018"(2018年01月19日 周五

13时37分39秒)的24个字符的字符串。

  time.strftime(fmt,[tupletime]) :接收以时间元组,并返回以可读字符串表示的当地时间,格式由fmt决定。

    如:  print(time.strftime('%Y-%m-%d %H:%M:%S %w', time.localtime()))

    输出:    2018-01-19 13:43:44 5  它的数据类型是str

  time.strptime(str, '%Y-%m-%d %H:%M:%S %w') :根据fmt的格式,把一个时间字符串,解析为时间元组。利用上面

返回的字符串,使用time.strptime()将它转化为时间元组:print(time.strptime(st, '%Y-%m-%d %H:%M:%S %w')),其中st

为接收time.strftime()的变量。返回结果:time.struct_time(tm_year=2018, tm_mon=1, tm_mday=19, tm_hour=13,

tm_min=50,tm_sec=24, tm_wday=4, tm_yday=19, tm_isdst=-1),这是一个时间元组。

  time.mktime(tupletime) :接受时间元组并返回时间辍(1970纪元后经过的浮点秒数)。

    如:

      

    这里的b是一个时间元组,记住在传时间元组时,如果是自己写元组,就必须去掉哪些英文简写,不然会报错,如果

是变量接收再传入,则不用考虑这个问题!

    返回:1516341024.0

  time.sleep() :推迟线程的执行。

 

 函数装饰器

装饰器(deco):
  装饰函数的参数是被装饰的函数对象,返回原函数对象,装饰器本质上是一个Python函数,它可以让其他函数在不需要

做任何代码变动的前提下增加额外功能,装饰器的返回值也是一个函数对象。

  概括的讲,装饰器的作用就是为已经存在的对象添加额外的功能。

  函数的装饰器本身接收一个闭包:

  

  函数装饰器就是在函数之前加一个:@+‘函数名’ ;如@f1

  加上@符合的时候,就将函数传入闭包,返回一个函数体,加括号传入参数就可以执行返回的函数。

 

   类的装饰器:类里面一定要写__call__方法,调用函数时实际上是调用__call__方法:

  

 

 三个常用的类装饰器

 

@property      把方法变成属性

  装饰过的函数返回的不再是一个函数,而是一个property对象

  装饰过后的方法不再是可调用的对象,可以看做数据属性直接访问。

   

  

 

@staticmethod #(静态方法)

  把没有参数的函数装饰过后变成可被实例调用的函数,

  函数定义时是没有参数的,可以不接收参数

  变成静态方法后,类名和实例都看看有调用;

  

  也可以在静态方法里传入参数,如果有参数,则调用的时候就一定要传参:

  

@classmethod (类方法) 有self,类名也可以调用!

  把装饰过的方法变成一个classmethod类对象,既能能被类调用又能被实例调用。

  注意参数是cls代表这个类本身。

   

 

 

一般来说,要使用某个类的方法,需要先实例化一个对象再调用方法。
而使用@staticmethod或@classmethod,就可以不需要实例化,直接类名.方法名()来调用。

 

 

类装饰器

  1 #!/usr/bin/env python
  2 # -*- coding: utf-8 -*-
  3 '''
  4 @File    :   class_decorator.py
  5 @Time    :   2024/06/19 22:41:23
  6 @Author  :   firstElfin 
  7 @Version :   1.0
  8 @Desc    :   None
  9 '''
 10 
 11 import inspect
 12 from abc import ABC, abstractmethod
 13 from threading import Lock
 14 
 15 components = {}
 16 
 17 class Component:
 18     def __call__(self, cls):
 19         if components.get(cls) is None: components[cls] = cls
 20         return components[cls]
 21 
 22 Service = Repository = Resource =  Component
 23 
 24 
 25 class Inject(ABC):
 26     name = "Inject"
 27 
 28     def __init__(self, **kwargs):
 29         self.kwargs = kwargs
 30 
 31     def __call__(self, obj):
 32         cls_init = obj.__init__
 33         
 34         def __sub_init(_self, *args, **kwargs):
 35             cls_init(_self, *args, **kwargs)
 36             self.inject_members(_self)
 37         
 38         obj.__init__ = __sub_init
 39         return obj
 40     
 41     def inject_members(self, obj):
 42         for name, clazz in self.kwargs.items():
 43             instance = self.get_instance(clazz)
 44             if instance: setattr(obj, name, instance)
 45     
 46     @abstractmethod
 47     def get_instance(self, cls): ...
 48 
 49 
 50 class InjectPrototype(Inject):
 51     name = "InjectPrototype"
 52 
 53     def get_instance(self, cls):
 54         clazz = components.get(cls)
 55         if clazz: return clazz()
 56         raise KeyError(f"不存在类型{cls!r}")
 57     
 58 
 59 class InjectSingleton(Inject):
 60     _instances = {}
 61     _lock = Lock()
 62     _class_lock = {}
 63 
 64     def get_instance(self, cls):
 65         instance = self._instances.get(cls)
 66         if not instance:
 67             class_lock = self._class_lock.get(cls)
 68             if not class_lock:
 69                 with self._lock:
 70                     class_lock = Lock()
 71                     self._class_lock[cls] = class_lock
 72             with class_lock:
 73                 instance = self._instances.get(cls)
 74                 if not instance:
 75                     clazz = components.get(cls)
 76                     instance = clazz()
 77                     self._instances[cls] = instance
 78         
 79         return instance
 80 
 81 
 82 @Repository()
 83 class UserRepository:
 84     def get(self, key):
 85         return f"User - {key!r}"
 86 
 87 
 88 @Repository()
 89 class ProductRepository:
 90     def get(self, key):
 91         return f"Product - {key!r}"
 92 
 93 
 94 #类装饰器可以使用InjectPrototype替换, InjectSingleton是单例模式
 95 InjectReplace = InjectSingleton
 96 
 97 
 98 @InjectReplace(product_repository=ProductRepository)
 99 @InjectReplace(user_repository=UserRepository)
100 @Service()
101 class EventService:
102     def update_info(self):
103         user = self.user_repository.get("Steven")
104         product = self.product_repository.get("Apple")
105         print(f"更新信息 {user} <> {product}")
106         # return f"更新信息 {user} <> {product}"
107 
108 
109 @InjectReplace(event_service=EventService)
110 class Client:
111     def execute(self):
112         self.event_service.update_info()
113 
114 
115 client = Client()
116 client2 = Client()
117 
118 client.execute()
119 client2.execute()
120 
121 print(id(client), id(client2))
122 print(id(client.event_service), id(client2.event_service))
123 print(id(client.event_service.user_repository), id(client2.event_service.user_repository))
124 print(id(client.event_service.product_repository), id(client2.event_service.product_repository))

 

 

类装饰器参考:

    1. 【提升Python技能】装饰器 (二) 类的装饰器_哔哩哔哩_bilibili

 

 

 

 

 

 

 

 

 

 

 

 

 

 

  

posted @ 2018-01-19 14:03  巴蜀秀才  阅读(368)  评论(0编辑  收藏  举报