Python:在类代码中显示分配给类对象的属性

Python:在类代码中显示分配给类对象的属性,python,Python,我的一个类对一组对象进行大量的聚合计算,然后为特定的对象分配一个适当的属性和值:即 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 t

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

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\u league\u standings
已经运行,每个队都有
team.place
。我希望能够扫描
类团队(对象)
的代码,并读取所有属性,这些属性都是由类方法创建的,也由操作类对象的外部方法创建的。我对在dir(team)中为p键入
:print p
只是为了查看属性名称有点厌倦了。我可以在团队
\uuuu init\uuuu
中定义一组空白的
属性。例如

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
计算联赛排名
返回
球队似乎是多余的

@property
def place(self): return self._place

我知道我可以在顶级的
类团队
中对属性列表进行注释,这是显而易见的解决方案,但我觉得这里必须有一个最佳实践,一些pythonic和优雅的东西

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

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

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

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

如果我对您的问题有一半的理解,您希望跟踪初始化后添加了实例的哪些属性。如果是这种情况,您可以使用以下内容:

#! /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)

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

请澄清这句话“然后分配、属性和值”。对我来说,如果
ld=LeagueDetails()
,然后
ld.calculate\u league\u standing()
,这意味着什么。它计算
place
值,并将该值分配给每个
团队的属性
place
。当我查看
类团队(对象)
的代码时,它没有显示显而易见的东西。。每个团队都有一个
team.place
属性。您编写的代码是错误的,因为您在方法之外使用了
self
。您的线路
self.team\u list=…
无法工作。你为什么不做一个
\uuuuu init\uuuuuu
方法来设置
self.team\u list
并调用
计算联赛积分
?并且在
\uuuuuu init\uuuuuu
的定义中必须有参数
self
,你应该用你自己的例子和“假人”一起属性-这并没有什么害处,根据编码标准,这是正确的方法。如果您要通过pylint(一个根据标准分析代码并查找错误的程序)运行代码,您会收到一条警告,即属性“place”是在init()之外定义的。在init中定义它有什么害处?我的问题都是关于可读性的,你的回答反映了我的总体倾向。我不想写工具,而是想写更好的代码。我越来越担心将一长串的
属性
分配给类对象是一种糟糕的风格,因为那些
属性
最终会成为一种
神秘的肉。我选择了另一个答案,因为它为我正在处理的实际项目创造了价值。不过,你的回答正是我想要讨论的类型。这段代码创造了各种各样的想法,我非常欣赏。当我在
\uuuu init\uuuuu(self)
之外分配属性时,我这样做只是为了能够显示结果。谢谢如果你能详细说明一下实际需求是什么,我很乐意提供更准确的帮助。