Hướng dẫn how do you overwrite a property in python? - làm thế nào để bạn ghi đè một thuộc tính trong python?

Vì vậy, tôi đang cố gắng tìm ra cách tốt nhất (thanh lịch nhất với số lượng mã ít nhất) để cho phép ghi đè các chức năng cụ thể của một thuộc tính (ví dụ: chỉ là getter, chỉ là setter, v.v.) trong Python. Tôi là một fan hâm mộ của 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 vào bắt đầu tiếp theo):

@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 đó, nói, ghi đè chức năng setter

>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
3, nó có vẻ khó khăn. 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à xác định các chức năng riêng biệt trong lớp cơ sở (ví dụ:
>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
4 và
>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
5), tạo rõ ràng định nghĩa thuộc tính từ chúng (ví dụ:
>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
6) và sau đó ghi đè
>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
4,
>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
5 và
>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
9 khi cần thiết.

Tôi không thích giải pháp này vì điều đó có nghĩa là tôi phải định nghĩa Lambas cho mỗi thuộc tính, và sau đó viết ra từng cuộc gọi chức năng (khi trước khi tôi có thể thực hiện

class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
0). Tôi cũng không nhận được sự đóng gói mà ban đầu tôi đã có.

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 C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
1 kế thừa hàm getter từ
class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
2 nhưng ghi đè chức năng setter. Có ai biết cách làm điều này (theo cách trông giống với ví dụ trên) không?
class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
3 sẽ trông như thế nào, và chức năng
>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
3 nên trả về?

Các tài liệu Python trên

class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
5 Trang trí cho thấy thành ngữ sau:

class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x

Và sau đó các lớp con có thể ghi đè một setter/getter duy nhất như thế này:

class C2(C):
   @C.x.getter
def x(self):
   return self._x * -1

Đây là một chút warty vì việc ghi đè nhiều phương thức dường như yêu cầu bạn phải làm một cái gì đó như:

class C3(C):
   @C.x.getter
def x(self):
   return self._x * -1
# C3 now has an x property with a modified getter
# so modify its setter rather than C.x 's setter.
@x.setter
def x(self, value):
   self._x = value * 2

Tôi chắc chắn rằng bạn đã nghe điều này trước đây, nhưng

class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
6 đã bị phản đối trong tám năm, kể từ Python 2.3. Không sử dụng nó. Việc bạn sử dụng
class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
7 cũng trái với Zen of Python - rõ ràng là tốt hơn tiềm ẩn. Nếu bạn thực sự thích vết lõm tăng lên, không cần phải tạo ra một đối tượng vứt bỏ, chỉ cần làmfor eight years, since Python 2.3. Don't use it. Your use of
class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
7 is also contrary to the Zen of Python -- explicit is better than implicit. If you really like the increased indentation, there is no need to create a throwaway object, just do

if True:
   @property
def foo(self):
   return self._foo
@foo.setter
def foo(self, val):
   self._foo = val

Nếu lớp con biết thuộc tính được xác định ở đâu, chỉ cần làm:

class ATimesTwo(A):
   @A.foo.setter
def foo(self, val):
   self._foo = val * 2

Ví dụ cho một thuộc tính hỗ trợ nối thêm các phương thức cho các chức năng đã đặt:

class ExtendableProperty(property):
   def append_setter(self, fset):
   # Create a wrapper around the new fset that also calls the current fset
_old_fset = self.fset

def _appended_setter(obj, value):
   _old_fset(obj, value)
fset(obj, value)
# Use that wrapper as setter instead of only the new fset
return self.setter(_appended_setter)

Việc sử dụng giống như đối với các thuộc tính bình thường, chỉ bây giờ có thể thêm các phương thức vào các setters thuộc tính:

class A(object):
   @ExtendableProperty
def prop(self):
   return self._prop

@prop.setter
def prop(self, v):
   self._prop = v

class B(A):
   @A.prop.append_setter
def prop(self, v):
   print('Set', v)

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


Gợi ý: 2

Chỉ ghi đè một getter, setter hoặc một đối tượng thuộc tính, chỉ ghi đè lên một getter, setter hoặc một dấu hiệu của một đối tượng thuộc tính, bắt đầu với ngôn ngữ Python, bắt đầu với ngôn ngữ Python

Khi bạn kế thừa từ một lớp có tài sản, bạn có thể cung cấp một triển khai mới cho một hoặc nhiều chức năng

class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
8,
class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
9 hoặc
class C2(C):
   @C.x.getter
def x(self):
   return self._x * -1
0, bằng cách tham chiếu đối tượng thuộc tính trên lớp cha:

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


Gợi ý: 3

Vì vậy, tôi đang cố gắng tìm ra cách tốt nhất (thanh lịch nhất với số lượng mã ít nhất) để cho phép ghi đè các chức năng cụ thể của một thuộc tính (ví dụ: chỉ là getter, chỉ là setter, v.v.) trong Python. Tôi là một fan hâm mộ của 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 vào tiếp theo bắt đầu) :, tất nhiên tại điểm mà bạn đang ghi đè Getter, Setter và Deleter Bạn có thể chỉ cần xác định lại thuộc tính cho C3., Tôi không thích giải pháp này vì điều đó có nghĩa là tôi phải xác định Lambas cho mọi thuộc tính và Sau đó viết ra mỗi cuộc gọi chức năng (khi trước khi tôi có thể thực hiện thuộc tính (** locals ())). Tôi cũng không nhận được sự đóng gói mà ban đầu tôi đã có.

Vì vậy, tôi đang cố gắng tìm ra cách tốt nhất (thanh lịch nhất với số lượng mã ít nhất) để cho phép ghi đè các chức năng cụ thể của một thuộc tính (ví dụ: chỉ là getter, chỉ là setter, v.v.) trong Python. Tôi là một fan hâm mộ của 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 vào bắt đầu tiếp theo):

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

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
3

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

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
4

Các tài liệu Python trên

class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
5 Trang trí cho thấy thành ngữ sau:

class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x

Và sau đó các lớp con có thể ghi đè một setter/getter duy nhất như thế này:

class C2(C):
   @C.x.getter
def x(self):
   return self._x * -1

Đây là một chút warty vì việc ghi đè nhiều phương thức dường như yêu cầu bạn phải làm một cái gì đó như:

class C3(C):
   @C.x.getter
def x(self):
   return self._x * -1
# C3 now has an x property with a modified getter
# so modify its setter rather than C.x 's setter.
@x.setter
def x(self, value):
   self._x = value * 2


Tôi chắc chắn rằng bạn đã nghe điều này trước đây, nhưng

class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
6 đã bị phản đối trong tám năm, kể từ Python 2.3. Không sử dụng nó. Việc bạn sử dụng
class C(object):
   def __init__(self):
   self._x = None
@property
def x(self):
   return self._x
@x.setter
def x(self, value):
   self._x = value
@x.deleter
def x(self):
   del self._x
7 cũng trái với Zen of Python - rõ ràng là tốt hơn tiềm ẩn. Nếu bạn thực sự thích vết lõm tăng lên, không cần phải tạo ra một đối tượng vứt bỏ, chỉ cần làm

Nếu lớp con biết thuộc tính được xác định ở đâu, chỉ cần làm:

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
8

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
9


Ví dụ cho một thuộc tính hỗ trợ nối thêm các phương thức cho các chức năng đã đặt:

Việc sử dụng giống như đối với các thuộc tính bình thường, chỉ bây giờ có thể thêm các phương thức vào các setters thuộc tính:

Gợi ý: 2

>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
0

Chỉ ghi đè một getter, setter hoặc một đối tượng thuộc tính, chỉ ghi đè lên một getter, setter hoặc một dấu hiệu của một đối tượng thuộc tính, bắt đầu với ngôn ngữ Python, bắt đầu với ngôn ngữ Python

>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
1

Lưu ý: Các biến riêng tư không thực sự tồn tại trong Python. Đơn giản là có các tiêu chuẩn để được tuân theo. Bản thân ngôn ngữ không áp dụng bất kỳ hạn chế nào.: The private variables don't actually exist in Python. There are simply norms to be followed. The language itself doesn't apply any restrictions.

>>> a = A()
>>> a.foo
8
>>> b = ATimesTwo()
>>> b.foo
16
2


Làm thế nào để bạn ghi đè một tài sản trong Python?

Hai cách để làm điều này là:..
Tài sản phân lớp. Cách đầu tiên để làm điều này là bằng cách phân lớp thuộc tính tích hợp và thêm các trình trang trí là các phiên bản của getter, setter và/hoặc deleter mở rộng các cuộc gọi lại, đặt và xóa các cuộc gọi lại hiện tại. ....
Ghi đè getter, setter và/hoặc deleter ..

Bạn có thể ghi đè lên một chức năng trong Python không?

Phương pháp ghi đè là khả năng của bất kỳ ngôn ngữ lập trình hướng đối tượng nào cho phép lớp con hoặc lớp con cung cấp một triển khai cụ thể của một phương thức đã được cung cấp bởi một trong các lớp siêu hoặc lớp của nó.

Bạn có thể ghi đè __ init __ không?

Trả lời #5: Có, bạn phải gọi __init__ cho mỗi lớp cha mẹ.Điều tương tự cũng xảy ra với các chức năng, nếu bạn đang ghi đè một chức năng tồn tại ở cả hai cha mẹ.Yes, you must call __init__ for each parent class. The same goes for functions, if you are overriding a function that exists in both parents.

Tài sản () làm gì trong Python?

Thuộc tính của Python () là cách pythonic để tránh các phương thức getter và setter chính thức trong mã của bạn.Hàm này cho phép bạn biến các thuộc tính lớp thành thuộc tính hoặc thuộc tính được quản lý.Vì thuộc tính () là một hàm tích hợp, bạn có thể sử dụng nó mà không cần nhập bất cứ thứ gì.allows you to turn class attributes into properties or managed attributes. Since property() is a built-in function, you can use it without importing anything.