Hàm thuộc tính bộ Python

PEP này mô tả một phần mở rộng cho Python, thêm từ điển thuộc tính vào các hàm và phương thức. PEP này theo dõi trạng thái và quyền sở hữu tính năng này. Nó chứa một mô tả về tính năng và phác thảo những thay đổi cần thiết để hỗ trợ tính năng. PEP này tóm tắt các cuộc thảo luận được tổ chức trong các diễn đàn danh sách gửi thư và cung cấp các URL để biết thêm thông tin, nếu thích hợp. Lịch sử sửa đổi CVS của tệp này chứa hồ sơ lịch sử cuối cùng

Các chức năng đã có một số thuộc tính, một số thuộc tính có thể ghi được, e. g.

def a[]:
    pass

a.publish = 1
a.unittest = '''...'''

if a.publish:
    print a[]

if hasattr[a, 'unittest']:
    testframework.execute[a.unittest]

class C:
    def a[self]:
        'just a docstring'
        a.publish = 1

c = C[]
if c.a.publish:
    publish[c.a[]]
4, một. k. a.
def a[]:
    pass

a.publish = 1
a.unittest = '''...'''

if a.publish:
    print a[]

if hasattr[a, 'unittest']:
    testframework.execute[a.unittest]

class C:
    def a[self]:
        'just a docstring'
        a.publish = 1

c = C[]
if c.a.publish:
    publish[c.a[]]
5.
def a[]:
    pass

a.publish = 1
a.unittest = '''...'''

if a.publish:
    print a[]

if hasattr[a, 'unittest']:
    testframework.execute[a.unittest]

class C:
    def a[self]:
        'just a docstring'
        a.publish = 1

c = C[]
if c.a.publish:
    publish[c.a[]]
4 có thuộc tính thú vị là có cú pháp đặc biệt trong định nghĩa hàm [và phương thức] để đặt thuộc tính ngầm. Sự tiện lợi này đã được khai thác nhiều lần, làm quá tải các chuỗi tài liệu với các ngữ nghĩa bổ sung

Ví dụ, John Aycock đã viết một hệ thống trong đó các chuỗi tài liệu được sử dụng để xác định các quy tắc phân tích cú pháp. ZPublisher ORB của Zope sử dụng chuỗi tài liệu để báo hiệu các phương pháp có thể xuất bản, tôi. e. các phương thức có thể được gọi thông qua web

Vấn đề với cách tiếp cận này là ngữ nghĩa quá tải có thể xung đột với nhau. Ví dụ: nếu chúng tôi muốn thêm bài kiểm tra đơn vị doctest vào phương thức Zope không thể xuất bản qua web

Đề xuất này bổ sung một từ điển mới cho các đối tượng chức năng, được gọi là

def a[]:
    pass

a.publish = 1
a.unittest = '''...'''

if a.publish:
    print a[]

if hasattr[a, 'unittest']:
    testframework.execute[a.unittest]

class C:
    def a[self]:
        'just a docstring'
        a.publish = 1

c = C[]
if c.a.publish:
    publish[c.a[]]
7 [a. k. a.
def a[]:
    pass

a.publish = 1
a.unittest = '''...'''

if a.publish:
    print a[]

if hasattr[a, 'unittest']:
    testframework.execute[a.unittest]

class C:
    def a[self]:
        'just a docstring'
        a.publish = 1

c = C[]
if c.a.publish:
    publish[c.a[]]
8]. Từ điển này có thể được đặt và nhận bằng cách sử dụng thuộc tính thông thường được đặt và nhận cú pháp

Các phương thức cũng có cú pháp getter và chúng hiện đang truy cập thuộc tính thông qua từ điển của đối tượng hàm bên dưới. Không thể đặt các thuộc tính trên các phương thức bị ràng buộc hoặc không bị ràng buộc, ngoại trừ bằng cách làm như vậy một cách rõ ràng trên đối tượng hàm bên dưới. Xem phần thảo luận bên dưới để biết cách tiếp cận trong các phiên bản tiếp theo của Python

Cũng có thể đặt

def a[]:
    pass

a.publish = 1
a.unittest = '''...'''

if a.publish:
    print a[]

if hasattr[a, 'unittest']:
    testframework.execute[a.unittest]

class C:
    def a[self]:
        'just a docstring'
        a.publish = 1

c = C[]
if c.a.publish:
    publish[c.a[]]
8 của đối tượng chức năng, nhưng chỉ cho đối tượng từ điển. Xóa một hàm
def a[]:
    pass

a.publish = 1
a.unittest = '''...'''

if a.publish:
    print a[]

if hasattr[a, 'unittest']:
    testframework.execute[a.unittest]

class C:
    def a[self]:
        'just a docstring'
        a.publish = 1

c = C[]
if c.a.publish:
    publish[c.a[]]
8 hoặc đặt nó thành bất kỳ thứ gì khác ngoài một đối tượng từ điển cụ thể sẽ dẫn đến một
class C:
    def a[self]: pass

c1 = C[]
c2 = C[]
c1.a.publish = 1
# c2.a.publish would now be == 1 also!
2. Nếu không có thuộc tính hàm nào được đặt, thì hàm
def a[]:
    pass

a.publish = 1
a.unittest = '''...'''

if a.publish:
    print a[]

if hasattr[a, 'unittest']:
    testframework.execute[a.unittest]

class C:
    def a[self]:
        'just a docstring'
        a.publish = 1

c = C[]
if c.a.publish:
    publish[c.a[]]
8 sẽ trống

Dưới đây là một số ví dụ về những gì bạn có thể làm với tính năng này

def a[]:
    pass

a.publish = 1
a.unittest = '''...'''

if a.publish:
    print a[]

if hasattr[a, 'unittest']:
    testframework.execute[a.unittest]

class C:
    def a[self]:
        'just a docstring'
        a.publish = 1

c = C[]
if c.a.publish:
    publish[c.a[]]

Paul Prescod đã liệt kê một loạt các cách sử dụng khác trên luồng python-dev

Dưới đây là một số hướng trong tương lai để xem xét. Bất kỳ việc áp dụng những ý tưởng này sẽ yêu cầu một PEP mới, tham chiếu ý tưởng này và sẽ phải được nhắm mục tiêu vào phiên bản Python sau phiên bản 2. 1 bản phát hành

  • Phiên bản trước của PEP này cho phép cả setter và getter của các thuộc tính trên các phương thức không liên kết và chỉ getter trên các phương thức liên kết. Một số vấn đề đã được phát hiện với chính sách này

    Bởi vì các thuộc tính của phương thức được lưu trữ trong hàm bên dưới, điều này gây ra một số kết quả có khả năng gây ngạc nhiên

    class C:
        def a[self]: pass
    
    c1 = C[]
    c2 = C[]
    c1.a.publish = 1
    # c2.a.publish would now be == 1 also!
    

    Vì thay đổi đối với

    class C:
        def a[self]: pass
    
    c1 = C[]
    c2 = C[]
    c1.a.publish = 1
    # c2.a.publish would now be == 1 also!
    
    4 bị ràng buộc với
    class C:
        def a[self]: pass
    
    c1 = C[]
    c2 = C[]
    c1.a.publish = 1
    # c2.a.publish would now be == 1 also!
    
    5 cũng gây ra thay đổi đối với
    class C:
        def a[self]: pass
    
    c1 = C[]
    c2 = C[]
    c1.a.publish = 1
    # c2.a.publish would now be == 1 also!
    
    4 bị ràng buộc với
    class C:
        def a[self]: pass
    
    c1 = C[]
    c2 = C[]
    c1.a.publish = 1
    # c2.a.publish would now be == 1 also!
    
    7, nên việc đặt thuộc tính trên các phương thức bị ràng buộc không được phép. Tuy nhiên, ngay cả việc cho phép đặt thuộc tính trên các phương thức không liên kết cũng có sự mơ hồ của nó

    class D[C]: pass
    class E[C]: pass
    
    D.a.publish = 1
    # E.a.publish would now be == 1 also!
    

    Vì lý do này, PEP hiện tại không cho phép đặt thuộc tính trên các phương thức liên kết hoặc không liên kết, nhưng cho phép nhận thuộc tính trên cả hai - cả hai đều trả về giá trị thuộc tính trên đối tượng hàm cơ bản

    Một PEP trong tương lai có thể đề xuất triển khai các thuộc tính phương thức cài đặt [liên kết hoặc không liên kết] bằng cách đặt các thuộc tính trên phiên bản hoặc lớp, sử dụng các quy ước đặt tên đặc biệt. Tôi. e

    ________số 8

    Ở đây, một tra cứu về cá thể sẽ tìm đến từ điển của cá thể trước, tiếp theo là tra cứu từ điển của lớp và cuối cùng là tra cứu từ điển của đối tượng hàm

  • Hiện tại, Python chỉ hỗ trợ các thuộc tính hàm trên các hàm Python [i. e. những cái được viết bằng Python, không phải những cái được tích hợp sẵn]. Nếu nó đáng giá, một bản vá riêng biệt có thể được tạo ra để thêm các thuộc tính chức năng vào các bản dựng sẵn
  • class C:
        def a[self]: pass
    
    c1 = C[]
    c2 = C[]
    c1.a.publish = 1
    # c2.a.publish would now be == 1 also!
    
    8 là thuộc tính chức năng duy nhất hiện có hỗ trợ cú pháp để thiết lập thuận tiện. Cuối cùng, có thể đáng để nâng cao ngôn ngữ để hỗ trợ cài đặt thuộc tính chức năng dễ dàng. Dưới đây là một số cú pháp được đề xuất bởi người đánh giá PEP

    def a[]:
        pass
    
    a.publish = 1
    a.unittest = '''...'''
    
    if a.publish:
        print a[]
    
    if hasattr[a, 'unittest']:
        testframework.execute[a.unittest]
    
    class C:
        def a[self]:
            'just a docstring'
            a.publish = 1
    
    c = C[]
    if c.a.publish:
        publish[c.a[]]
    
    0

    BDFL hiện đang chống lại mọi hỗ trợ cú pháp đặc biệt như vậy để đặt các thuộc tính chức năng tùy ý. Mọi đề xuất cú pháp sẽ phải được phác thảo trong PEP mới

Khi điều này được thảo luận trong danh sách gửi thư của python-dev vào tháng 4 năm 2000, một số ý kiến ​​bất đồng đã được đưa ra. Để hoàn thiện, chủ đề thảo luận bắt đầu trên python-dev

Các đối số bất đồng dường như thuộc các loại sau

  • không có mục đích rõ ràng [nó mua gì cho bạn?]
  • những cách khác để làm điều đó [e. g. ánh xạ dưới dạng thuộc tính lớp]
  • vô dụng cho đến khi hỗ trợ cú pháp được bao gồm

Chống lại một số lập luận này là quan sát rằng với vanilla Python 2. 0,

class C:
    def a[self]: pass

c1 = C[]
c2 = C[]
c1.a.publish = 1
# c2.a.publish would now be == 1 also!
8 trên thực tế có thể được đặt thành bất kỳ loại đối tượng nào, do đó, một số thuộc tính hàm có thể ghi đã khả thi. Nhưng cách tiếp cận đó lại là một tham nhũng khác của
class C:
    def a[self]: pass

c1 = C[]
c2 = C[]
c1.a.publish = 1
# c2.a.publish would now be == 1 also!
8

Và mặc dù có thể thêm ánh xạ vào các đối tượng lớp [hoặc trong trường hợp các thuộc tính hàm, vào mô-đun của hàm], nhưng việc trích xuất các giá trị thuộc tính để kiểm tra sẽ khó khăn hơn và ít rõ ràng hơn.

Cuối cùng, có thể mong muốn thêm hỗ trợ cú pháp, giống như cách hỗ trợ cú pháp của

class C:
    def a[self]: pass

c1 = C[]
c2 = C[]
c1.a.publish = 1
# c2.a.publish would now be == 1 also!
8 tồn tại. Điều này có thể được xem xét tách biệt với khả năng thực sự thiết lập và nhận các thuộc tính chức năng

Hàm thuộc tính thiết lập được sử dụng để làm gì trong Python?

Hàm setattr[] đặt giá trị của thuộc tính được chỉ định của đối tượng được chỉ định .

Có thể gán các thuộc tính cho một chức năng?

Mỗi chức năng có một số thuộc tính bổ sung có thể được truy cập bằng cú pháp dấu chấm [e. g. chức năng. __Tên__ ]. Hàm tích hợp dir trả về danh sách các thuộc tính có sẵn của một đối tượng được chỉ định. Kể từ Python 2. 1, hàm có thể có thuộc tính tùy ý , tức là bạn có thể sử dụng hàm làm bộ lưu trữ khóa-giá trị.

__ Setattr __ hoạt động như thế nào trong Python?

Hàm setattr của Python chấp nhận một đối tượng [đối tượng mà chúng ta đang thêm thuộc tính vào], một chuỗi biểu thị tên thuộc tính và một giá trị để gán. In each iteration of our for loop, we're assigning a new attribute on our Row object [remember self points to our class instance].

Chủ Đề