YOLOv8目标跟踪代码BaseTrack中关于类属性的用法
flyfish
源码是
py
class BaseTrack:
_count = 0
def __init__(self):
"""Initializes a new track with unique ID and foundational tracking attributes."""
self.track_id = 0
self.is_activated = False
self.state = TrackState.New
self.history = OrderedDict()
self.features = []
self.curr_feature = None
self.score = 0
self.start_frame = 0
self.frame_id = 0
self.time_since_update = 0
self.location = (np.inf, np.inf)
@property
def end_frame(self):
"""Return the last frame ID of the track."""
return self.frame_id
@staticmethod
def next_id():
"""Increment and return the global track ID counter."""
BaseTrack._count += 1
return BaseTrack._count
id1 = BaseTrack.next_id() # id1 == 1
id2 = BaseTrack.next_id() # id2 == 2
id3 = BaseTrack.next_id() # id3 == 3
print(id1)
print(id2)
print(id3)
_count
是 BaseTrack
类的一个类属性。类属性是类本身的属性,而不是实例属性,它在类的所有实例之间共享。
静态方法 next_id
使用 BaseTrack._count += 1
来递增类属性 _count
,并返回新的值。
还有以下方式实现该效果
1. 使用类方法(Class Methods)
py
class BaseTrack:
_count = 0
def __init__(self):
"""Initializes a new track with unique ID and foundational tracking attributes."""
self.track_id = BaseTrack.next_id()
@classmethod
def next_id(cls):
"""Increment and return the global track ID counter."""
cls._count += 1
return cls._count
# 示例使用
track1 = BaseTrack()
print(track1.track_id) # 输出 1
track2 = BaseTrack()
print(track2.track_id) # 输出 2
2. 使用单例模式(Singleton Pattern)
py
class SingletonBaseTrack:
_instance = None
_count = 0
def __new__(cls, *args, **kwargs):
if cls._instance is None:
cls._instance = super(SingletonBaseTrack, cls).__new__(cls)
return cls._instance
def __init__(self):
"""Initializes a new track with unique ID and foundational tracking attributes."""
self.track_id = self.next_id()
def next_id(self):
SingletonBaseTrack._count += 1
return SingletonBaseTrack._count
# 示例使用
track1 = SingletonBaseTrack()
print(track1.track_id) # 输出 1
track2 = SingletonBaseTrack()
print(track2.track_id) # 输出 2
3. 使用模块级别的变量
两个不同的文件之间的共享
py
# global_counter.py
_count = 0
def next_id():
global _count
_count += 1
return _count
# main.py
from global_counter import next_id
class BaseTrack:
def __init__(self):
"""Initializes a new track with unique ID and foundational tracking attributes."""
self.track_id = next_id()
# 示例使用
track1 = BaseTrack()
print(track1.track_id) # 输出 1
track2 = BaseTrack()
print(track2.track_id) # 输出 2
4. 使用装饰器模式
py
def with_counter(cls):
cls._count = 0
original_init = cls.__init__
def new_init(self, *args, **kwargs):
original_init(self, *args, **kwargs)
self.track_id = cls.next_id()
cls.__init__ = new_init
@classmethod
def next_id(cls):
cls._count += 1
return cls._count
cls.next_id = next_id
return cls
@with_counter
class BaseTrack:
def __init__(self):
"""Initializes a new track with unique ID and foundational tracking attributes."""
pass
# 示例使用
track1 = BaseTrack()
print(track1.track_id) # 输出 1
track2 = BaseTrack()
print(track2.track_id) # 输出 2
5. 使用类的内部类
可以在类内部定义一个共享状态的类,这样可以在所有实例中共享该内部类的属性。
py
class BaseTrack:
class SharedState:
_count = 0
@classmethod
def next_id(cls):
cls._count += 1
return cls._count
def __init__(self):
"""Initializes a new track with unique ID and foundational tracking attributes."""
self.track_id = BaseTrack.SharedState.next_id()
# 示例使用
track1 = BaseTrack()
print(track1.track_id) # 输出 1
track2 = BaseTrack()
print(track2.track_id) # 输出 2
6. 使用类工厂函数
#类工厂函数可以生成具有共享状态的类。
py
def create_base_track_class():
_count = 0
class BaseTrack:
@staticmethod
def next_id():
nonlocal _count
_count += 1
return _count
def __init__(self):
"""Initializes a new track with unique ID and foundational tracking attributes."""
self.track_id = BaseTrack.next_id()
return BaseTrack
BaseTrack = create_base_track_class()
# 示例使用
track1 = BaseTrack()
print(track1.track_id) # 输出 1
track2 = BaseTrack()
print(track2.track_id) # 输出 2
7. 使用闭包(Closure)
通过闭包可以创建带有共享状态的工厂函数。
py
def base_track_factory():
_count = 0
class BaseTrack:
def __init__(self):
nonlocal _count
_count += 1
self.track_id = _count
return BaseTrack
BaseTrack = base_track_factory()
# 示例使用
track1 = BaseTrack()
print(track1.track_id) # 输出 1
track2 = BaseTrack()
print(track2.track_id) # 输出 2
可以根据需要选择,对比着看 ,类属性和类方法是最直接,对于更复杂的需求再选其他。