0

我的一个类对一组对象进行大量聚合计算,然后分配一个适合特定对象的属性和值:即

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我可以在 Team 中定义一堆空白__init__。例如

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 和优雅的东西。

4

2 回答 2

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)

如果我不明白这个问题,请说明我错了哪一部分。

于 2013-03-03T19:35:47.120 回答
1

由于 Python 的动态特性,我不相信您的问题有一个普遍的答案。可以通过多种方式设置实例的属性,包括纯赋值setattr()、 和写入__dict__。编写一个工具来静态分析 Python 代码并通过分析所有这些方法来正确确定类的所有可能属性将非常困难。

在您的特定情况下,作为您所知道的程序员,class Team在许多情况下都会有一个 place 属性,因此您可以决定显式地编写它的构造函数,如下所示:

class Team(object):
def __init__(name ,place=None):
    self.name = name
    self.place = place

我想说没有必要定义简单属性的属性,除非您希望在读取或写入时发生副作用或派生。

于 2013-03-03T19:30:52.413 回答