Выполнить функцию, не отправляя ей «себя» - PullRequest
3 голосов
/ 15 марта 2011

Возможно ли определить функцию без ссылки на self таким образом?

def myfunc(var_a,var_b)

Но чтобы он также мог получать данные отправителя, как если бы я определил их так:

def myfunc(self, var_a,var_b)

То, что self всегда одно и то же, поэтому здесь всегда выглядит несколько избыточным, чтобы запускать функцию следующим образом: myfunc(self,'data_a','data_b'). Тогда я хотел бы получить свои данные в функции, как это sender.fields.

UPDATE: Вот код, чтобы лучше понять, что я имею в виду. Приведенный ниже класс используется для отображения страницы, основанной на шаблонизаторе Jinja2, для регистрации пользователями.

class SignupHandler(webapp.RequestHandler):
    def get(self, *args, **kwargs):
        utils.render_template(self, 'signup.html')

И этот код ниже - render_template, который я создал как оболочку для функций Jinja2, чтобы использовать его более удобно в моем проекте:

def render_template(response, template_name, vars=dict(), is_string=False):
    template_dirs = [os.path.join(root(), 'templates')]
    logging.info(template_dirs[0])
    env = Environment(loader=FileSystemLoader(template_dirs))
    try:
        template = env.get_template(template_name)
    except TemplateNotFound:
        raise TemplateNotFound(template_name)
    content = template.render(vars)
    if is_string:
        return content
    else:
        response.response.out.write(content)

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

Ответы [ 4 ]

9 голосов
/ 15 марта 2011

Если вам не нужно self, вы можете использовать декоратор staticmethod для создания метода, который не получает объект в качестве первого аргумента:

class Foo(object):
    @staticmethod
    def foo(bar, baz, qux):
        pass

Если вы пишете код, который имеет дело только с глобальными данными, напротив, вы можете использовать метод класса:

class Foo(object):
    global_cache={}
    @classmethod
    def set(cls, key, value):
        cls.global_cache[key] = value

Если, напротив, вы пишете код, который действительно должен ссылаться на экземпляр объекта - self является частью языка. Часть Zen of Python заключается в том, что «явное лучше, чем неявное», и использование self является примером этого.

2 голосов
/ 15 марта 2011

Чтобы вызвать функцию, которая существует в классе, но не должна ничего знать о себе (без удаления аргумента self), можно использовать staticmethod .

Примером этого может быть

class Person:

  @staticmethod
  def barbar(arg1, arg2, arg3):
    # Has no idea of the class or instance in which this was called on.
    pass

Чтобы вызвать это, вы должны сделать что-то вроде:

Person.barbar("hi","bye","jump")
1 голос
/ 16 марта 2011

Похоже, вы должны создать свой собственный подкласс webapp.RequestHandler и определить для него свой метод render_template:

class MyRequestHandler(webapp.RequestHandler):
    def render_template(self, template_name, vars=dict(), is_string=False):
        # Body of render_template, with "request" replaced with "self" ...

Затем вы используете его следующим образом:

class SignupHandler(MyRequestHandler):
    def get(self, *args, **kwargs):
        self.render_template('signup.html')
1 голос
/ 15 марта 2011

Вам не нужно писать self, это просто соглашение, но когда вызывается метод объекта, он передается объекту в качестве первого аргумента, поэтому вам придется дать ему имя.В плотном коде, разработанном на моем телефоне, я использовал s ранее, а при взаимодействии с кодом C ++ я использовал this, но обычно лучше использовать self


Update0

Ой, подождите, вы не определяете объектный метод.Может быть, так и должно быть, тогда вы запускаете object.func(*args, **kwargs), а не func(object, *args, **kwargs).Мне нужно посмотреть, что ты пытаешься сделать, чтобы понять, что уместно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...