我的一个类对一组对象进行了大量的聚合计算,然后分配了一个适合特定对象的属性和值:I.e。
class Team(object):
def __init__(self, name): # updated for typo in code, added self
self.name = name
class LeagueDetails(object):
def __init__(self): # added for clarity, corrected another typo
self.team_list = [Team('name'), ...]
self.calculate_league_standings() # added for clarity
def calculate_league_standings(self):
# calculate standings as a team_place_dict
for team in self.team_list:
team.place = team_place_dict[team.name] # a new team attribute
我知道,只要calculate_league_standings
已经投放,每个团队都有team.place
。我希望能够做的是扫描class Team(object)
的代码并读取所有属性,这些属性既可以通过类方法创建,也可以通过对类对象进行操作的外部方法创建。我有点不耐烦地输入for p in dir(team): print p
只是为了查看属性名称是什么。我可以在团队attributes
中定义一堆空白__init__
。 E.g。
class Team(object):
def __init__(self, name): # updated for typo in code, added self
self.name = name
self.place = None # dummy attribute, but recognizable when the code is scanned
让calculate_league_standings
返回team._place
然后添加
@property
def place(self): return self._place
我知道我可以在顶部class Team
评论一个属性列表,这是显而易见的解决方案,但我觉得这里必须有一个最佳实践,这里有一些pythonic和优雅。
答案 0 :(得分:1)
由于Python的动态特性,我不相信你的问题有一个通用的答案。可以通过多种方式设置实例的属性,包括纯分配setattr()
和写入__dict__
。编写一个工具来静态分析Python代码并通过分析所有这些方法正确地确定类的所有可能属性将非常困难。
在您的特定情况下,作为程序员,您知道class Team
在许多实例中将具有place属性,因此您可以决定显式并编写其构造函数,如下所示:
class Team(object):
def __init__(name ,place=None):
self.name = name
self.place = place
我想说没有必要定义一个简单属性的属性,除非你想在读或写时发生副作用或派生。
答案 1 :(得分:1)
如果我一半了解您的问题,您希望跟踪初始化后添加了实例的哪些属性。如果是这种情况,您可以使用以下内容:
#! /usr/bin/python3.2
def trackable (cls):
cls._tracked = {}
oSetter = cls.__setattr__
def setter (self, k, v):
try: self.initialized
except: return oSetter (self, k, v)
try: self.k
except:
if not self in self.__class__._tracked:
self.__class__._tracked [self] = []
self.__class__._tracked [self].append (k)
return oSetter (self, k, v)
cls.__setattr__ = setter
oInit = cls.__init__
def init (self, *args, **kwargs):
o = oInit (self, *args, **kwargs)
self.initialized = 42
return o
cls.__init__ = init
oGetter = cls.__getattribute__
def getter (self, k):
if k == 'tracked': return self.__class__._tracked [self]
return oGetter (self, k)
cls.__getattribute__ = getter
return cls
@trackable
class Team:
def __init__ (self, name, region):
self.name = name
self.region = region
#set name and region during initialization
t = Team ('A', 'EU')
#set rank and ELO outside (hence trackable)
#in your "aggregate" functions
t.rank = 4 # a new team attribute
t.ELO = 14 # a new team attribute
#see witch attributes have been created after initialization
print (t.tracked)
如果我不明白这个问题,请指明我错了哪一部分。