Я просто собираюсь запуститься с подсказки от меня :)
Использование os.path.dirname () в settings.py для предотвращения hardcoded dirnames.
не Делают hardcode пути в Вашем settings.py, если Вы хотите выполнить свой проект в различных местоположениях. Используйте следующий код в settings.py, если Ваши шаблоны и статические файлы расположены в каталоге проекта Django:
# settings.py
import os
PROJECT_DIR = os.path.dirname(__file__)
...
STATIC_DOC_ROOT = os.path.join(PROJECT_DIR, "static")
...
TEMPLATE_DIRS = (
os.path.join(PROJECT_DIR, "templates"),
)
Кредиты: Я получил эту подсказку от скринкаста' Django С нуля '.
Все, что вы хотели знать об Атрибутах и методах Python .
Да, это косвенный ответ, но он демонстрирует ряд методов и объясняет некоторые из более сложные детали и «магия».
Для «более прямого» ответа рассмотрим новый модуль python . В частности, посмотрите на функцию instancemethod, которая позволяет «привязать» метод к экземпляру - в данном случае это позволит вам использовать «self» в методе.
import new
class Z(object):
pass
z = Z()
def method(self):
return self
z.q = new.instancemethod(method, z, None)
z is z.q() # true
Если вы привязываетесь к экземпляру, вы не должны включать аргумент self:
>>> class Foo(object):
... pass
...
>>> def donothing():
... pass
...
>>> f = Foo()
>>> f.x = donothing
>>> f.x()
>>>
Вам действительно нужен аргумент self, если вы привязываетесь к классу:
>>> def class_donothing(self):
... pass
...
>>> foo.y = class_donothing
>>> f.y()
>>>
Ваш пример запутан и сложен, и я не совсем понимаю, какое отношение он имеет к вашему вопросу. Не стесняйтесь уточнить, если хотите.
Однако сделать то, что вы хотите, довольно легко, если я правильно понимаю ваш вопрос.
class Foo(object):
def bar(self):
print('bar')
def baz():
print('baz')
В переводчике ...
>>> f = Foo()
>>> f.bar()
bar
>>> f.bar = baz
>>> f.bar()
baz
>>> g = Foo()
>>> g.bar()
bar
>>> f.bar()
baz
Если вам когда-нибудь понадобится сделать это для специального метода (который для класса нового стиля - это то, что вы всегда должны использовать, и единственный в Python 3 - ищется в классе, а не в экземпляре), вы можете просто создать класс для каждого экземпляра, например ...:
self.foo = Foo()
meths = {'__str__': lambda self: 'peekaboo!'}
self.foo.__class__ = type('yFoo', (Foo,), meths)
Изменить : Меня попросили разъяснить преимущества этот подход к new.instancemethod ...:
>>> class X(object):
... def __str__(self): return 'baah'
...
>>> x=X()
>>> y=X()
>>> print x, y
baah baah
>>> x.__str__ = new.instancemethod(lambda self: 'boo!', x)
>>> print x, y
baah baah
Как видите, метод new.instance в данном случае совершенно бесполезен. OTOH ...:
>>> x.__class__=type('X',(X,),{'__str__':lambda self:'boo!'})
>>> print x, y
boo! baah
... назначение нового класса отлично подходит как для этого случая, так и для любого другого. Кстати, как я надеюсь, понятно, как только вы сделаете это с данным экземпляром, вы сможете позже добавить больше методов и других атрибутов класса к его x .__ class __
и по сути повлиять только на этот экземпляр!
Не делайте этого.
Изменение методов одного экземпляра - это просто неправильно.
Вот правила объектно-ориентированного дизайна.
Избегайте магии.
Если вы не можете использовать наследование, используйте делегирование.
Это означает, что каждый раз, когда вы думаете, что вам нужно что-то волшебное, вы должен был написать «оболочку» или фасад вокруг объекта, чтобы добавить необходимые вам функции.
Просто напишите оболочку.