2009-07-13 40 views
7

Tôi đang cố gắng sử dụng một chút kế thừa trong một chương trình Python mà tôi đang làm việc. Tôi có một lớp cơ sở, Người dùng, thực hiện tất cả chức năng của người dùng. Tôi đang thêm khái niệm về một người dùng không được chấp thuận, giống như một người dùng, với việc bổ sung một phương thức duy nhất.Làm thế nào để bạn đưa một thể hiện vào một lớp dẫn xuất?

Lớp người dùng có một số phương thức trả về đối tượng Người dùng. Điều này sẽ không hoạt động khi tôi phân lớp, vì tôi sẽ kết thúc có một Người dùng không được chấp thuận trả lại một Người dùng, ngăn tôi gọi phương thức này, trong số những thứ khác.

class User(object): 
    base_dn = 'ou=Users,dc=example,dc=org' 

    @classmethod 
    def get(cls, uid): 
     ldap_data = LdapUtil.get(uid + ',' + self.base_dn) 
     return User._from_ldap(ldap_data) 

class UnapprovedUser(User): 
    base_dn = 'ou=UnapprovedUsers,dc=example,dc=org' 

    def approve(self): 
     new_dn = '' # the new DN 
     LdapUtil.move(self.dn, new_dn) 

Các get()_from_ldap() phương pháp là như nhau cho cả hai lớp, mặc dù get() phương pháp trong UnapprovedUser cần phải trả lại một đối tượng UnapprovedUser, không phải là một tài khoản.

Tôi làm cách nào để truyền một trong các phiên bản Người dùng mà tôi nhận được từ User.get() vào Người dùng không được chấp thuận?

tôi muốn làm một cái gì đó như:

class UnapprovedUser(User): 
    # continued from before 

    @classmethod 
    def get(cls, uid): 
     user = super(UnapprovedUser, cls).get(uid) 
     return (UnapprovedUser) user # invalid syntax 

để tôi có thể quấn phương pháp từ cha mẹ và chỉ cần đúc giá trị trả về đến lớp đúng. Sau đó, một lần nữa, làm theo cách đó có thể dẫn đến phụ huynh sử dụng giá trị của chúng cho self.base_dn, điều này sẽ phá vỡ mọi thứ.

Trả lời

7

Thay vì "truyền", tôi nghĩ bạn thực sự muốn tạo một UnapprovedUser thay vì User khi gọi UnapprovedUser.get(). Để làm điều đó:

Thay đổi User.get thực sự sử dụng cls lập luận đó là thông qua trong:

@classmethod 
def get(cls, uid): 
    ldap_data = LdapUtil.get(uid + ',' + self.base_dn) 
    return cls._from_ldap(ldap_data) 

Bạn sẽ cần phải làm một cái gì đó tương tự trong _from_ldap. Bạn không liệt kê mã cho _from_ldap, nhưng tôi cho rằng tại một số điểm nó làm điều gì đó như:

result = User(... blah ...) 

Bạn muốn thay thế này với:

result = cls(... blah ...) 

Hãy nhớ rằng: trong Python một đối tượng lớp là một cuộc gọi có thể tạo ra các cá thể của lớp đó. Vì vậy, bạn có thể sử dụng tham số cls của một classmethod để xây dựng các cá thể của lớp được sử dụng để gọi classmethod.

+0

Chính xác những gì tôi đang tìm kiếm. Cảm ơn. Tôi đoán tôi không bao giờ nhận thấy rằng bạn có thể làm điều đó với tham số cls vào một phương thức lớp. –

2

Python là ngôn ngữ được nhập động, do đó khái niệm "truyền" không tồn tại. Nếu đối tượng đã là UnapprovedUser, thì bạn đã có thể gọi tất cả các phương thức tồn tại trong lớp đó mà không phải truyền.

+2

vấn đề là tôi nhận được một tài khoản trả lại cho tôi, nhưng tôi cần nó để được một UnapprovedUser để tôi có thể gọi đó là m ethod. Tôi không muốn lặp lại mã nếu tôi không phải. –

+4

"Đúc" là một chút của một thuật ngữ không rõ ràng (do đó có n loại khác nhau của phôi trong C++), nhưng chắc chắn có một cái gì đó giống như ít nhất một dạng đúc trong Python: loại chuyển đổi. ví dụ: Tôi có thể tưởng tượng một người nào đó nói rằng str (x) "phôi" x vào một str (mặc dù tôi nghĩ rằng hầu hết mọi người sẽ đi cho rõ ràng hơn "chuyển đổi" hơn là "phôi"). –

0

Trong một phương thức lớp, lớp được chuyển vào trong tham số cls. Vì vậy, thay vì User.something làm cls.something. Làm xong!

Điều đó nói rằng, tôi không chắc chắn tôi sẽ làm điều này với hai loại người dùng. Tôi không chắc chắn 100% ý bạn là "Chấp thuận" ở đây, tôi có vẻ như là một trong hai điều.

  1. Điều đó có nghĩa là người dùng chưa thực sự đăng nhập. Trong trường hợp đó, tôi sẽ có một cá thể Người dùng ẩn danh đặc biệt cho người dùng chưa đăng nhập. Vì bạn đang di chuyển DN khi phê duyệt, điều này dường như có nhiều khả năng là những gì bạn đang làm.

  2. Điều đó có nghĩa là người dùng chưa được chấp thuận là thành viên đầy đủ hoặc nội dung nào đó. Đây chỉ là trường hợp đặc biệt cho phép xử lý và có thể bạn sẽ muốn có nhiều quyền hơn sau này. Thay vào đó, tôi sẽ thêm hỗ trợ cho vai trò người dùng và đặt vai trò "Được chấp thuận".

Nếu bạn muốn nói điều gì khác được chấp thuận, vui lòng bỏ qua điều này. :-)

+0

Tôi có cấu trúc thư mục LDAP đơn giản mà tôi sẽ lưu trữ người dùng. Ou = Người dùng được người dùng 'Chấp thuận' sử dụng. Các ứng dụng nhìn vào thư mục để tìm thông tin đăng nhập chỉ tìm trong ou = Users. Tôi cũng có cách để người dùng yêu cầu quyền truy cập vào các ứng dụng này, nơi họ yêu cầu phê duyệt từ quản trị viên trước khi họ có thể đăng nhập. Trong trường hợp này, chúng được tạo trong ou = Người dùng không được chấp thuận và được chuyển đến ou = Người dùng bằng cách sử dụng phương thức 'approval()'. Vì vậy, không cần thêm cấp độ nào. –

+0

OK, sau đó nguyên tắc có ý nghĩa. (Mặc dù tất nhiên, có phương pháp phê duyệt trên người dùng chuẩn không bị tổn thương, vì vậy bạn có thể không cần hai lớp khác nhau). –

1
  • siêu (UnapprovedUser, tự) là sai nó phải siêu (UnapprovedUser, cls) bởi vì trong phương pháp lớp học mà bạn không cần phải tự sẵn

  • Tôi sẽ nhắc lại câu hỏi của bạn, trong cơ sở lớp bạn đang tạo người dùng và bằng cách nào đó bạn muốn trả về lớp dẫn xuất


    class User(object): 

     @classmethod 
     def get(cls, uid): 
      return User() 

    class UnapprovedUser(User): 

     @classmethod 
     def get(cls, uid): 
      user = super(UnapprovedUser, cls).get(uid) 
      return user # invalid syntax 

    print UnapprovedUser.get("XXX") 

nó in đối tượng tài khoản thay vì UnapprovedUser đối tượng đây bạn muốn UnapprovedUser.get trở UnapprovedUser, cho rằng bạn có thể tạo một hàm nhà máy mà wil trở lại sử dụng thích hợp và hơn điền vào nó với ldap


    class User(object): 

     @classmethod 
     def get(cls, uid): 
      return cls.getMe() 

     @classmethod 
     def getMe(cls): 
      return cls() 

    class UnapprovedUser(User): 

     @classmethod 
     def get(cls, uid): 
      user = super(UnapprovedUser, cls).get(uid) 
      return user 

    print UnapprovedUser.get("XXX") 

nó in đối tượng UnapprovedUser

Các vấn đề liên quan