从列表中,动态创建名称感知

时间:2018-03-02 21:49:08

标签: python python-3.x introspection

我试图编写一个简单的控制台颜色实用程序,该实用程序需要一个充满ANSI代码的类,并在我的控制台实用程序上生成一些辅助方法,因此我可以console.add('text', 'blue')执行console.blue('text')而不是def blue(self, s): 1}}。

我知道我可以静态地定义所有这些(例如class _AnsiColors: def __init__(self): self.green = 35 self.red = 1 self.blue = 32 self.yellow = 214 self.amber = 208 self.olive = 106 self.orange = 166 self.purple = 18 self.pink = 197 self.gray = 243 self.dark_gray = 238 self.light_gray = 248 self.black = 0 self.white = 255 self.debug = 24 ansi = _AnsiColors() ),但如果我想添加100个左右的帮助器,那么这并不能很好地扩展(不是我想要的,但是如果... 的)

这是简单的ANSI地图:

pyfancy

控制台实用程序(将方法代理到colors并使用import copy from colors import color from pyfancy import * from ansi import ansi class console(object): def __init__(self, s): self._s = pyfancy(s) def add(self, s, c='white'): if hasattr(ansi, self.add.__name__): c = self.add.__name__ self._s.add(color(s, fg=getattr(ansi, c))) return self def bold(self, s): self._s.bold(s) return self def raw(self, s): self._s.raw(s) return self def dim(self, s): self._s.dim(s) return self def print(self): self._s.output() # Inject ansi color convenience methods for c in vars(ansi): setattr(console, c, copy.deepcopy(console.add)) getattr(console, c).__name__ = c ):

console('raw').bold(' bold').raw(' raw').blue(' blue').red(' red').print()

然后我可以像这样使用它:

blue

您可以看到助手方法redadd()至少执行,因此我对copy.deepcopy的复制有效,但这里发生了什么(即使我认为我可以使用__name__)解决问题,当我尝试设置每个方法副本的add属性时,它会将引用设置为ansi.debug,而我最终会所有彩色输出都是相同的颜色(import copy from ansi import ansi class console(object): def __init__(self, s): self._s = s def add(self, s, c='white'): if hasattr(ansi, self.add.__name__): c = self.add.__name__ self._s += '%s(%s)' % (s, c) return self def print(self): print(self._s) # Inject ansi color convenience methods for c in vars(ansi): setattr(console, c, copy.deepcopy(console.add)) getattr(console, c).__name__ = c console('white').blue(' blue').red(' red').print() # white blue(debug) red(debug) )。

有没有办法在没有静态定义每个助手的情况下做我想做的事情?

MCVE没有颜色/ pyfancy:

string

1 个答案:

答案 0 :(得分:1)

我会用一个闭包解决它:

class console(object):
    def __init__(self, s):
        self._s = s
        for color in vars(ansi):
            self._colorizer(color)

    def _colorizer(self, c):        
        def add(s):
            self._s += '%s(%s)' % (s, c)
            return self

        self.__setattr__(c, add)

    def print(self):
        print(self._s)

console('white').blue(' blue').red(' red').print()
# white blue(blue) red(red)