Как представить пользовательский объект Python в виде строки при использовании в качестве аргумента в другой функции? - PullRequest
1 голос
/ 11 июля 2019

Я пытаюсь создать простой объект с именем Color.Я хочу, чтобы это имело ту же функциональность, что и строка, закодированная как шестнадцатеричный цвет.Похоже, что он работает, но не имеет тех же возможностей.

Редактировать: В ответ на принятый ответ ниже:

import pandas as pd
from matplotlib.colors import to_rgb, rgb2hex


class Color(str):
    def __new__(cls, value, *args, **kwargs):
        # explicitly only pass value to the str constructor
        cls.color = rgb2hex(to_rgb(value))
        return super(Color, cls).__new__(cls, cls.color)

x = pd.Series([Color("fuchsia"), Color("black")])
print(x)
# 0    #ff00ff
# 1    #000000
# dtype: object
print("Should be fuchsia but it's black", x[0].color)
# Should be fuchsia but it's black #000000
print("Should be black", x[0].color)
# Should be black #000000

Оригинал:

Например,следующие операции работают:

print(color)
print(pd.Series(color))
print(to_rgb(str(color)))

, но это не так:

print(to_rgb(color))

Я не могу понять, почему это не работает.Я пробовал это, но это не соответствует случаю: Python, представить не строковый объект в виде строки?

from matplotlib.colors import hex2color, to_rgb, to_rgba


class Color(object):
    # Built in
    def __init__(self, color):
        self.color = rgb2hex(to_rgb(color))
    def __repr__(self):
        return self.color
    def __str__(self):
        return self.color

color = Color("black")
print(color)
# #000000
print(pd.Series(color))
# 0    #000000
# dtype: object
print(to_rgb(str(color)))
# (0.0, 0.0, 0.0)
print(to_rgb(color))

Вот ошибка:

---------------------------------------------------------------------------
KeyError                                  Traceback (most recent call last)
~/anaconda/envs/µ_env/lib/python3.6/site-packages/matplotlib/colors.py in to_rgba(c, alpha)
    173     try:
--> 174         rgba = _colors_full_map.cache[c, alpha]
    175     except (KeyError, TypeError):  # Not in cache, or unhashable.

KeyError: (#000000, None)

During handling of the above exception, another exception occurred:

ValueError                                Traceback (most recent call last)
<ipython-input-35-a478f942e1d2> in <module>
     16 print(pd.Series(color))
     17 print(to_rgb(str(color)))
---> 18 print(to_rgb(color))

~/anaconda/envs/µ_env/lib/python3.6/site-packages/matplotlib/colors.py in to_rgb(c)
    279 def to_rgb(c):
    280     """Convert *c* to an RGB color, silently dropping the alpha channel."""
--> 281     return to_rgba(c)[:3]
    282 
    283 

~/anaconda/envs/µ_env/lib/python3.6/site-packages/matplotlib/colors.py in to_rgba(c, alpha)
    174         rgba = _colors_full_map.cache[c, alpha]
    175     except (KeyError, TypeError):  # Not in cache, or unhashable.
--> 176         rgba = _to_rgba_no_colorcycle(c, alpha)
    177         try:
    178             _colors_full_map.cache[c, alpha] = rgba

~/anaconda/envs/µ_env/lib/python3.6/site-packages/matplotlib/colors.py in _to_rgba_no_colorcycle(c, alpha)
    225         # float)` and `np.array(...).astype(float)` all convert "0.5" to 0.5.
    226         # Test dimensionality to reject single floats.
--> 227         raise ValueError("Invalid RGBA argument: {!r}".format(orig_c))
    228     # Return a tuple to prevent the cached value from being modified.
    229     c = tuple(c.astype(float))

ValueError: Invalid RGBA argument: #000000

1 Ответ

2 голосов
/ 11 июля 2019

Может быть, вы хотите подкласс str для предоставления вашей строки.

import pandas as pd
from matplotlib.colors import to_rgb, rgb2hex


class Color(str):
    def __new__(cls, value, *args, **kwargs):
        # explicitly only pass value to the str constructor
        v = rgb2hex(to_rgb(value))
        return super(Color, cls).__new__(cls, v)


color = Color("fuchsia")

print(color)
print(pd.Series(color))
print(to_rgb(str(color)))
print(to_rgb(color))

выходы

#ff00ff
0    #ff00ff
dtype: object
(1.0, 0.0, 1.0)
(1.0, 0.0, 1.0)

Если вы хотите сохранить начальное значение внутри вашей строки, вы можете сделать это

class Color(str):
    def __new__(cls, value, *args, **kwargs):
        # explicitly only pass value to the str constructor
        v = rgb2hex(to_rgb(value))
        return super(Color, cls).__new__(cls, v)

    def __init__(self, value):
        self.color = value
...