gpt4 book ai didi

python - 在python中构建类方法属性的字典

转载 作者:太空宇宙 更新时间:2023-11-03 18:01:01 25 4
gpt4 key购买 nike

我正在尝试将类中的函数组织成组。我决定向类中的每个函数添加一个属性,并使用设置属性值的记录。我想要制作一个字典,也许当调用该类时,键将是我设置的属性,值是方法。这是代码示例:

def orientation(lr):
def decorator(f):
f.orientation = lr
return f
return decorator

def level(lr):
def decorator(f):
f.level = lr
return f
return decorator

class Artwork(object):
def __init__(self):
self.groups = {}

def __call__(self):
pass

@level('good')
@orientation(RIGHT)
def build_one(self):
return """ some stuff """

@level('bad')
@orientation(RIGHT)
def build_two(self):
return """ some stuff """

@level('bad')
@orientation(RIGHT)
def build_three(self):
return """ some stuff """

如果能返回这样的东西那就太好了:

test = Artwork()
test.groups
>> {'good': [build_one], 'bad': [build_two, build_three]}

我尝试使用反射来循环遍历类并使用 hasattr 查找属性,但我似乎无法让它工作。

更新:

我有另一个继承 Artwork 的 Art 类。在艺术课上,我想从“组”中调用随机函数。目前,我手动设置要使用的函数,但我试图通过设置可以根据某些初始条件随机调用的函数组来使其更加健壮。

class Art(Artwork, object):

""" Here is where instead of setting the available_art manually,
I will use the dict of groups of art functions.
i.e. {'bad': [func1, func2], 'good': [func3, func5, func6]} """
def __init__(self, text, score):
self.text = text
self.available_art = [self.build_one,
self.build_two,
self.build_three,
self.build_four]
self.score = score

def _decide_rank(self):
total = functools.reduce(operator.add, self.score.values())
passing = self.score.get('passing')
percentage = (passing / total) * 100
rank = SCORE_MAP[percentage] if percentage in SCORE_MAP else SCORE_MAP[min(SCORE_MAP.keys(), key=lambda k: abs(k-percentage))]
return rank

def _get_longest_line(self, text):
lines = text.split('\n')
return len(max(lines, key=len))

def _build_bubble(self, text, spaces, orientation, length=40):
bubble = []
right = True if orientation == 'right' else False
lines = self._normalize_text(text, length)
bordersize = len(lines[0])

rline = ' ' * spaces + ' ' + '-' * bordersize
lline = ' ' + '-' * bordersize
plines = rline if right else lline

bubble.append(plines)

for index, line in enumerate(lines):
border = self._get_border(lines, index, spaces, right)
bubble.append('%s %s %s' % (border[0], line, border[1]))

bubble.append(plines)

return '\n'.join(bubble)

def _normalize_text(self, text, length):
lines = textwrap.wrap(text, length)
maxlen = len(max(lines, key=len))
return [line.ljust(maxlen) for line in lines]

def _get_border(self, lines, index, spaces, right):
if len(lines) < 2:
return [' ' * spaces + '<', '>'] if right else [' ' + '<', '>']
elif index == 0:
return [' ' * spaces + '/', '\\'] if right else ['/', '\\']
elif index == len(lines) - 1:
return [' ' * spaces + '\\', '/'] if right else ['\\', '/']
else:
return [' ' * spaces + '|', '|'] if right else ['|', '|']

def _randomizer(self):
return random.randrange(0, len(self.available_art))

def build(self):
pic = self.available_art[self._randomizer()]
spaces = self._get_longest_line(pic())
orientation = pic.orientation
print self._build_bubble(self.text, spaces, orientation) + pic()

最佳答案

您可以使用 dir() 迭代这些方法,如下所示:

Artwork.groups = {}
for attr in dir(Artwork):
try:
v = getattr(Artwork, attr).level
except AttributeError:
pass # level-less
else:
Artwork.groups.setdefault(v, []).append(attr)

现在这两种形式都可以工作,因为 groups 是在类级别设置的(您只需删除 self.groups = {} 行,因为它隐藏了类级别成员):

Artwork.groups
=> {'bad': ['build_three', 'build_two'], 'good': ['build_one']}
Artwork().groups
=> {'bad': ['build_three', 'build_two'], 'good': ['build_one']}

使用dir比直接访问Artwork.__dict__更好,因为这也支持继承(假设您确实希望子类继承级别他们的父类(super class))

更新

如果您需要将其应用于多个类,请将其设为函数:

def add_groups(cls):
cls.groups = {}
for attr in dir(cls):
try:
v = getattr(cls, attr).level
except AttributeError:
pass # level-less
else:
cls.groups.setdefault(v, []).append(attr)

然后应用它:

add_groups(Artwork)
add_groups(Art)

或者,如果您愿意,您可以使用类装饰器。

关于python - 在python中构建类方法属性的字典,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27670788/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com