2017-02-22 16 views
8

Câu hỏi này đặt câu hỏi ngược lại với Inherit namedtuple from a base class in python, trong đó mục đích là kế thừa một lớp con từ một tệp có tên và không ngược lại.Thừa kế từ một lớp cơ sở có tên là - Python

Trong thừa kế bình thường, hoạt động này:

class Y(object): 
    def __init__(self, a, b, c): 
     self.a = a 
     self.b = b 
     self.c = c 


class Z(Y): 
    def __init__(self, a, b, c, d): 
     super(self.__class__, self).__init__(a, b, c) 
     self.d = d 

[ra]:

>>> Z(1,2,3,4) 
<__main__.Z object at 0x10fcad950> 

Nhưng nếu baseclass là một namedtuple:

from collections import namedtuple 

X = namedtuple('X', 'a b c') 

class Z(X): 
    def __init__(self, a, b, c, d): 
     super(self.__class__, self).__init__(a, b, c) 
     self.d = d 

[ra]:

>>> Z(1,2,3,4) 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
TypeError: __new__() takes exactly 4 arguments (5 given) 

Câu hỏi, là có thể kế thừa các tệp có tên là một lớp cơ sở bằng Python không? Vậy sao?

Trả lời

12

Bạn có thể, nhưng bạn phải ghi đè __new__ được gọi là ngầm trước __init__:

class Z(X): 
    def __new__(cls, a, b, c, d): 
    self = super(Z, cls).__new__(cls, a, b, c) 
    self.d = d 
    return self 

>>> z = Z(1, 2, 3, 4) 
>>> z 
Z(a=1, b=2, c=3) 
>>> z.d 
4 

Nhưng d sẽ chỉ là một thuộc tính độc lập!

>>> list(z) 
[1, 2, 3] 
+0

Tôi có thể làm 'self.append (d)'? – alvas

+0

@alvas Không, bởi vì 'namedtuple' về cơ bản là một' tuple' (không thay đổi theo thiết kế và do đó không có 'append') – MSeifert

+0

@Mseifert Cảm ơn! Nhưng = ( – alvas

3

Tôi nghĩ rằng bạn có thể đạt được những gì bạn muốn bằng cách bao gồm tất cả các lĩnh vực trong tuple tên ban đầu, sau đó điều chỉnh số lượng các đối số sử dụng __new__ như schwobaseggl gợi ý ở trên. Ví dụ, để giải quyết trường hợp max, nơi một số các giá trị đầu vào được phải được tính toán chứ không phải là cung cấp trực tiếp, các công việc sau:

from collections import namedtuple 

class A(namedtuple('A', 'a b c computed_value')): 
    def __new__(cls, a, b, c): 
     computed_value = (a + b + c) 
     return super(A, cls).__new__(cls, a, b, c, computed_value) 

>>> A(1,2,3) 
A(a=1, b=2, c=3, computed_value=6) 
Các vấn đề liên quan