Trình thiết lập thuộc tính ghi đè Python

Tôi hiện đang sử dụng trình trang trí @property để đạt được "getters and setters" trong một vài lớp học của mình. Tôi ước có thể kế thừa các phương thức @property này trong một lớp con

Tôi có một số mã Python [cụ thể là tôi đang làm việc trong py3k] trông hơi giống như vậy

class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:
    @property
    def attr[self]:
        return A.attr   # The bit that doesn't work.

    @attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]

Tôi đã đánh dấu phần không hoạt động bằng nhận xét. Tôi muốn trả về attr getter của lớp cơ sở.

class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]
1 trả về một đối tượng thuộc tính [có lẽ rất gần với những gì tôi cần. ]

Chỉnh sửa.
Sau khi nhận được câu trả lời bên dưới từ Ned, tôi đã nghĩ ra một giải pháp mà tôi nghĩ là hợp lý hơn cho vấn đề này.

class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]

Trình trang trí

class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]
2 mong đợi một đối tượng thuộc tính mà chúng ta có thể nhận được bằng cách sử dụng
class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]
3. Điều này có nghĩa là chúng ta không phải khai báo lại thuộc tính trong lớp con

[Đây là sự khác biệt giữa giải quyết một vấn đề vào cuối ngày so với giải quyết nó vào đầu ngày. ]

Vì vậy, tôi đang cố gắng tìm ra cách tốt nhất [tinh tế nhất với ít mã nhất] để cho phép ghi đè các chức năng cụ thể của một thuộc tính [e. g. , chỉ getter, chỉ setter, v.v. ] trong trăn. Tôi là người yêu thích cách thực hiện các thuộc tính sau đây, do thực tế là tất cả các phương thức của chúng được gói gọn trong cùng một khối mã được thụt lề [dễ dàng hơn để xem các hàm xử lý một thuộc tính dừng ở đâu và các hàm xử lý

@apply
def foo[]:
    """A foobar"""
    def fget[self]:
        return self._foo
    def fset[self, val]:
        self._foo = val
    return property[**locals[]]

Tuy nhiên, nếu tôi muốn kế thừa từ một lớp xác định các thuộc tính theo cách này, và sau đó, giả sử, ghi đè hàm thiết lập

class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]
4, thì có vẻ phức tạp. Tôi đã thực hiện một số tìm kiếm và hầu hết các câu trả lời tôi tìm thấy là định nghĩa các hàm riêng biệt trong lớp cơ sở [e. g.
class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]
5 và
class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]
6], tạo rõ ràng định nghĩa thuộc tính từ chúng [e. g.
class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]
7], sau đó ghi đè lên
class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]
5,
class A:
    @property
    def attr[self]:
        try:
            return self._attr
        except AttributeError:
            return ''

class B[A]:        
    @A.attr.setter
    def attr[self, value]:
        self._attr = value

if __name__ == '__main__':
    b = B[]
    print['Before set:', repr[b.attr]]
    b.attr = 'abc'
    print[' After set:', repr[b.attr]]
6 và
@apply
def foo[]:
    """A foobar"""
    def fget[self]:
        return self._foo
    def fset[self, val]:
        self._foo = val
    return property[**locals[]]
0 nếu cần

Tôi không thích giải pháp này vì nó có nghĩa là tôi phải xác định lambas cho từng thuộc tính riêng lẻ, sau đó viết ra từng lời gọi hàm [khi trước đó tôi có thể vừa thực hiện

class A[object]:
    def __init__[self]:
        self.foo = 8
    @apply
    def foo[]:
        """A foobar"""
        def fget[self]:
            return self._foo
        def fset[self, val]:
            self._foo = val
        return property[**locals[]]

class ATimesTwo[A]:
    @some_decorator
    def foo[]:
        def fset[self, val]:
            self._foo = val * 2
        return something
0]. Tôi cũng không nhận được sự đóng gói mà tôi đã có ban đầu

Lý tưởng nhất, những gì tôi muốn có thể làm sẽ là một cái gì đó như thế này

class A[object]:
    def __init__[self]:
        self.foo = 8
    @apply
    def foo[]:
        """A foobar"""
        def fget[self]:
            return self._foo
        def fset[self, val]:
            self._foo = val
        return property[**locals[]]

class ATimesTwo[A]:
    @some_decorator
    def foo[]:
        def fset[self, val]:
            self._foo = val * 2
        return something

Và sau đó đầu ra sẽ trông giống như

>>> a = A[]
>>> a.foo
8
>>> b = ATimesTwo[]
>>> b.foo
16

Về cơ bản,

class A[object]:
    def __init__[self]:
        self.foo = 8
    @apply
    def foo[]:
        """A foobar"""
        def fget[self]:
            return self._foo
        def fset[self, val]:
            self._foo = val
        return property[**locals[]]

class ATimesTwo[A]:
    @some_decorator
    def foo[]:
        def fset[self, val]:
            self._foo = val * 2
        return something
1 kế thừa hàm getter từ
class A[object]:
    def __init__[self]:
        self.foo = 8
    @apply
    def foo[]:
        """A foobar"""
        def fget[self]:
            return self._foo
        def fset[self, val]:
            self._foo = val
        return property[**locals[]]

class ATimesTwo[A]:
    @some_decorator
    def foo[]:
        def fset[self, val]:
            self._foo = val * 2
        return something
2 nhưng ghi đè hàm setter. Có ai biết cách thực hiện việc này không [theo cách tương tự như ví dụ trên]?

Bạn có thể ghi đè thuộc tính bằng Python không?

Nó hoạt động tốt với cách sử dụng thuộc tính lỗi thời của bạn -- chỉ cần thực hiện foo = property[fget, fset] như bình thường. Nếu bạn muốn ghi đè một thuộc tính trong một lớp con tùy ý, bạn có thể sử dụng một công thức như thế này . Lưu ý nếu bạn muốn bộ xóa ngoài setter, thì trình trang trí cho bộ xóa phải là @foo.

Tôi có nên sử dụng getters và setters trong Python không?

Mặc dù mẫu getter và setter khá phổ biến trong các ngôn ngữ lập trình khác, nhưng đó không phải là trường hợp trong Python. Việc thêm các phương thức getter và setter vào lớp học của bạn có thể làm tăng đáng kể số dòng trong mã của bạn .

Python setter là gì?

Trình thiết lập là phương thức đặt giá trị của thuộc tính . Trong OOP, điều này giúp đặt giá trị thành các thuộc tính riêng tư trong một lớp. Về cơ bản, sử dụng getters và setters đảm bảo đóng gói dữ liệu. Lý do chúng tôi sử dụng setters và getters là. Để hoàn thành việc đóng gói.

Trình trang trí thuộc tính Python là gì?

@property là trình trang trí tích hợp sẵn cho hàm property[] trong Python . Nó được sử dụng để cung cấp chức năng "đặc biệt" cho một số phương thức nhất định để làm cho chúng hoạt động như getters, setters hoặc deleters khi chúng ta định nghĩa các thuộc tính trong một lớp.

Chủ Đề