Могу ли я добавлять собственные методы/атрибуты к встроенным типам Python? - программирование
Подтвердить что ты не робот

Могу ли я добавлять собственные методы/атрибуты к встроенным типам Python?

Например, я хочу добавить метод helloWorld() к типу типа Python. Могу ли я это сделать?

JavaScript имеет объект-прототип, который ведет себя таким образом. Возможно, это плохой дизайн, и я должен подклассифицировать объект dict, но тогда он работает только в подклассах, и я хочу, чтобы он работал над любыми будущими словарями.

Вот как это будет выглядеть в JavaScript:

String.prototype.hello = function() {
    alert("Hello, " + this + "!");
}
"Jed".hello() //alerts "Hello, Jed!"

Здесь полезная ссылка с большим количеством примеров — http://www.javascriptkit.com/javatutors/proto3.shtml

4b9b3361

Ответ 1

Вы не можете напрямую добавить метод к исходному типу. Однако вы можете подклассифицировать тип, затем подставить его во встроенное/глобальное пространство имен, которое достигает большей части желаемого эффекта. К сожалению, объекты, созданные с помощью литерального синтаксиса, по-прежнему будут иметь тип ванили и не будут иметь ваши новые методы/атрибуты.

Здесь он выглядит как

# Built-in namespace
import __builtin__

# Extended subclass
class mystr(str):
    def first_last(self):
        if self:
            return self[0] + self[-1]
        else:
            return ''

# Substitute the original str with the subclass on the built-in namespace    
__builtin__.str = mystr

print str(1234).first_last()
print str(0).first_last()
print str('').first_last()
print '0'.first_last()

output = """
14
00

Traceback (most recent call last):
  File "strp.py", line 16, in <module>
    print '0'.first_last()
AttributeError: 'str' object has no attribute 'first_last'
"""

Ответ 2

Да, путем подклассификации этих типов. См. объединение типов и классов в Python.

Нет, это не означает, что фактические dicts будут иметь этот тип, потому что это будет путать. Подкласс встроенного типа является предпочтительным способом добавления функциональности.

Ответ 3

Только что попробовал запрещенный фрукт!

вот код, очень просто!

from forbiddenfruit import curse


def list_size(self):
    return len(self)

def string_hello(self):
    print("Hello, {}".format(self))

if __name__ == "__main__":
    curse(list, "size", list_size)
    a = [1, 2, 3]
    print(a.size())
    curse(str, "hello", string_hello)
    "Jesse".hello()

Ответ 4

class MyString:
    def __init__(self, string):
        self.string = string
    def bigger_string(self):
        print(' '.join(self.string))

mystring = MyString("this is the string")
mystring.bigger_string()

выход

t h i s   i s   t h e   s t r i n g

Dataclass в Python 3.7

from dataclasses import dataclass

@dataclass
class St:

    text : str

    def bigger(self) -> None:
        self.text = list(self.text)
        print(" ".join(self.text))

mys = St("Hello")
mys.bigger()

выход

H e l l o

Ответ 5

ПРИМЕЧАНИЕ: этот QA помечен как дубликат этого, но IMO требует чего-то другого. Я не могу ответить там, поэтому я отвечаю здесь.


В частности, я хотел унаследовать от str и добавить пользовательские атрибуты. Существующие ответы (особенно те, которые говорят, что вы не можете) не совсем решили, но это сработало для меня:

class TaggedString(str):
    """
    A ''str'' with a ''.tags'' set and ''.kwtags'' dict of tags.
    Usage example::
      ts = TaggedString("hello world!", "greeting", "cliche",
                        what_am_i="h4cker")
      (ts.upper(), ts.tags, ts.kwtags)
    """

    def __new__(cls, *args, **kwargs):
        return super().__new__(cls, args[0])

    def __init__(self, s, *tags, **kwtags):
        super().__init__()
        self.tags = set(tags)
        self.kwtags = kwtags

Надеюсь, это кому-нибудь поможет! Cheers,
Andres

Ответ 6

Подкласс - это путь к Python. Программисты Polyglot учатся использовать правильный инструмент для правильной ситуации - в разумных пределах. То, что искусно сконструировано как Rails (DSL, использующее Ruby), очень трудно реализовать на языке с более жестким синтаксисом, подобным Python. Люди часто сравнивают двух, говорящих, как они похожи. Сравнение несколько несправедливо. Python светит по-своему. totochto.