2011-06-24 33 views
8

Tôi có một handler Yêu cầu và trang trí, tôi muốn làm việc với các đối tượng tự bên trong trang tríTiếp cận đối số chức năng từ trang trí

class MyHandler(webapp.RequestHandler): 

    @myDecorator 
     def get(self): 
      #code 

Cập nhật: Xin lưu ý sự khác biệt giữa tự đầu tiên và thứ hai

class myDecorator(object): 

    def __init__(self, f): 
     self.f = f 

    def __call__(self): 
     #work with self 
  1. MyHandler>get (chức năng)>self (argument)
  2. myDecorator>__call__ (chức năng)>self (argument)

các đối số tự nêu trên là khác nhau. Ý định của tôi là truy cập vào bản thân đầu tiên từ bên trong hàm __call__, hoặc tìm cách để làm một việc tương tự.

Xin chào, tôi có thể truy cập vào đối số tự MyHandlers từ lấy hàm bên trong trình trang trí không?

Update2: Tôi muốn thực hiện một trang trí để làm việc với một tên đăng nhập tùy chỉnh trong công cụ google app:

Tôi có một lớp (RequestHandler):

class SomeHandler(webapp.RequestHandler): 
    @only_registered_users 
    def get(self): 
     #do stuff here 

Và tôi muốn trang trí có chức năng để kiểm tra xem người dùng có đăng nhập hay không:

from util.sessions import Session 
import logging 

class only_registered_users(object): 

    def __init__(self, f): 
     self.f = f 

    def __call__(self): 
     def decorated_get(self): 
     logging.debug("request object:", self.request) 
     session = Session() 

     if hasattr(session, 'user_key'): 
      return self.f(self) 
     else: 
      self.request.redirect("/login") 


    return decorated_get 

Tôi biết nếu sử dụng r được đăng nhập nếu có thuộc tính 'user_key' trong một đối tượng phiên.

Đó là mục tiêu chính Tôi quan tâm đến về trường hợp cụ thể này

Hãy cho tôi biết đề xuất của bạn/ý kiến ​​nếu tôi làm điều gì đó sai!

Cảm ơn!

+0

Ngoài ra, đặt "Google App Engine" trước một câu hỏi mà chỉ khoảng trang trí có thể làm cho câu hỏi của bạn có được quan điểm ít hơn. Các mục chung được xem rất nhiều, các câu hỏi về các nền tảng cụ thể được xem và trả lời chậm hơn. – marr75

+0

Đã sửa, cảm ơn @ marr75 –

+1

Không vấn đề gì, nếu câu hỏi của bạn được xem nhiều hơn, câu trả lời của tôi có thể được bỏ phiếu nhiều hơn. Đó là một chiến thắng. – marr75

Trả lời

9

Tôi không hoàn toàn rõ ràng bạn muốn gì, nhưng nếu bạn chỉ muốn sử dụng các đối số của hàm được trang trí, thì đó chính xác là những gì một trình trang trí cơ bản làm. Vì vậy, để truy cập nói, self.request từ một trang trí bạn có thể làm:

def log_request(fn): 
    def decorated_get(self): 
     logging.debug("request object:", self.request) 
     return fn(self) 
    return decorated_get 

class MyHandler(webapp. RequestHandler): 
    @log_request 
    def get(self): 
     self.response.out.write('hello world') 

Nếu bạn đang cố gắng truy cập vào các lớp chức năng trang trí được gắn vào, sau đó nó là một chút tricker và bạn sẽ có để lừa một chút sử dụng mô-đun inspect.

import inspect 

def class_printer(fn): 
    cls = inspect.getouterframes(inspect.currentframe())[1][3] 
    def decorated_fn(self, msg): 
     fn(self,cls+" says: "+msg) 
    return decorated_fn 

class MyClass(): 
    @class_printer 
    def say(self, msg): 
     print msg 

Trong ví dụ trên, chúng tôi lấy tên của lớp từ khung hiện tại (trong khi thực thi trang trí) và sau đó lưu trữ trong chức năng được trang trí.Ở đây chúng ta chỉ cần thêm tên lớp vào bất kỳ biến số msg là trước khi chuyển nó sang hàm say gốc, nhưng bạn có thể sử dụng trí tưởng tượng của mình để làm những gì bạn thích khi bạn có tên lớp.

>>> MyClass().say('hello') 
MyClass says: hello 
+0

Tôi vừa cập nhật vấn đề để làm cho nó rõ ràng hơn, tôi thấy tôi có thể sử dụng kiểm tra cho lớp, nhưng tôi muốn sử dụng các đối số của các chức năng trang trí. Điều đó có thể không? thx @Chris –

+0

Xin lỗi vẫn không rõ ràng những gì bạn đang cố gắng đạt được ... nhưng tôi đã cập nhật câu trả lời với một số thông tin khác anyway –

+0

Tôi đã thêm Cập nhật mới (2) với trường hợp cụ thể, vui lòng cho tôi biết ý kiến ​​của bạn. Cảm ơn rất nhiều! –

1

Hãy thử phương pháp này: Can a Python decorator of an instance method access the class?

Không phải là cùng một câu hỏi chính xác nhưng bạn sẽ có thể sử dụng phương pháp tương tự để tạo ra một tài liệu tham khảo để tự hoặc một tham chiếu đến một cuốn từ điển với các đối tượng của một lớp nào đó trong nó mà bạn có thể nhận ra trong trang trí của bạn.

0

Đối số self để __call__ sẽ được điền bằng phương thức trang trí đang được gọi. Không có cách nào để truy cập đối tượng trang trí từ đây - __call__ là một phương pháp bị ràng buộc, và những gì bạn đang yêu cầu sẽ yêu cầu nó, có hiệu lực, 'bị ràng buộc gấp đôi'. Python không hỗ trợ điều này, do đó, cá thể trang trí được thay thế bằng đối số đầu tiên của hàm được trang trí.

Cách dễ nhất để giải quyết vấn đề này là sử dụng các hàm lồng nhau, như @Chris đề xuất.

1
import random 

#decorator to the get function in order to check out if the user is logged in or not 
def only_registered_users(func): 
    def wrapper(handler): 
     print 'Checking if user is logged in' 
     if random.randint(0, 1): 
      print 'User is logged in. Calling the original function.' 
      func(handler) 
     else: 
      print 'User is NOT logged in. Redirecting...' 
      # redirect code here 
    return wrapper 


class MyHandler(object): 

    @only_registered_users 
    def get(self): 
     print 'Get function called' 



m = MyHandler() 
m.get() 
1

source

def p_decorate(func): 
    def func_wrapper(name): 
     return "<p>{0}</p>".format(func(name)) 
    return func_wrapper 

@p_decorate 
def get_text(name): 
    return "lorem ipsum, {0} dolor sit amet".format(name) 

print get_text("John") 

# Outputs <p>lorem ipsum, John dolor sit amet</p> 
Các vấn đề liên quan