Могу ли я добавить собственные методы / атрибуты во встроенные типы Python? - PullRequest
57 голосов
/ 15 января 2011

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

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

Вот как это будет происходить в JavaScript:

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

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

Ответы [ 4 ]

62 голосов
/ 15 января 2011

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

Вот как это выглядит

# 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'
"""
1 голос
/ 09 мая 2019

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

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

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()
1 голос
/ 15 января 2011

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

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

0 голосов
/ 05 июля 2013

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

...