Python có các biến riêng tư của người dùng trong các lớp không?


578

Tôi đến từ thế giới Java và đọc các mô hình, công thức và thành ngữ Python 3 của Bruce Eckels .

Trong khi đọc về các lớp, nó tiếp tục nói rằng trong Python không cần phải khai báo các biến thể hiện. Bạn chỉ cần sử dụng chúng trong constructor, và boom, chúng ở đó.

Ví dụ:

class Simple:
    def __init__(self, s):
        print("inside the simple constructor")
        self.s = s

    def show(self):
        print(self.s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

Nếu đó là sự thật, thì bất kỳ đối tượng nào của lớp Simplechỉ có thể thay đổi giá trị của biến sbên ngoài lớp.

Ví dụ:

if __name__ == "__main__":
    x = Simple("constructor argument")
    x.s = "test15" # this changes the value
    x.show()
    x.showMsg("A message")

Trong Java, chúng tôi đã được dạy về các biến công khai / riêng tư / được bảo vệ. Những từ khóa này có ý nghĩa bởi vì đôi khi bạn muốn các biến trong một lớp mà không ai bên ngoài lớp có quyền truy cập.

Tại sao điều đó không bắt buộc trong Python?


17
Bạn có nghĩa là ví dụ biến, không phải lớp biến, phải không?
PaulMcG

13
Bạn nên kiểm tra các thuộc tính: docs.python.org/l Library / fiances.html # property . Chỉ cần sử dụng getter và biến của bạn sẽ được bảo vệ.
rubik

Một câu trả lời ngắn gọn và sắc nét là ở đây . Hy vọng điều này có thể giúp cho bạn.
Premkumar chalmeti

Câu trả lời:


962

Đó là văn hóa. Trong Python, bạn không ghi vào các biến thể hiện hoặc lớp của các lớp khác. Trong Java, không có gì ngăn cản bạn làm điều tương tự nếu bạn thực sự muốn - sau tất cả, bạn luôn có thể chỉnh sửa nguồn của chính lớp để đạt được hiệu quả tương tự. Python giảm giả vờ bảo mật và khuyến khích các lập trình viên có trách nhiệm. Trong thực tế, điều này hoạt động rất độc đáo.

Nếu bạn muốn mô phỏng các biến riêng tư vì một số lý do, bạn luôn có thể sử dụng __tiền tố từ PEP 8 . Python đọc tên của các biến như thế __foođể chúng không dễ dàng nhìn thấy mã bên ngoài lớp có chứa chúng (mặc dù bạn có thể xoay quanh nó nếu bạn đủ quyết tâm, giống như bạn có thể đi xung quanh các biện pháp bảo vệ của Java nếu bạn làm việc với nó ).

Theo cùng một quy ước, _tiền tố có nghĩa là tránh xa ngay cả khi bạn không bị ngăn chặn về mặt kỹ thuật . Bạn không chơi xung quanh với các biến khác của lớp khác trông giống như __foohoặc _bar.


14
Điều đó có ý nghĩa. Tuy nhiên, tôi không nghĩ rằng có bất kỳ cách nào trong java để truy cập các biến riêng tư bên ngoài lớp (ngoại trừ thực sự thay đổi nguồn của lớp học). Lanhung?
khắp nơi vào

168
Tôi có xu hướng thích cách python, nhưng tôi không nghĩ cách java là vô nghĩa như bạn làm. Khai báo một cái gì đó riêng tư nhanh chóng cho ai đó đọc mã một cái gì đó rất hữu ích: trường này chỉ được sửa đổi trong lớp này.
Ned

67
@ Đại diện, bạn có thể sử dụng sự phản chiếu.
rapadura

77
Hãy để tôi nói thẳng điều này, vì vậy Python không triển khai các thuộc tính công cộng hay riêng tư vì "đó là giả vờ bảo mật và khuyến khích các lập trình viên chịu trách nhiệm", tuy nhiên cộng đồng có khuyến khích sử dụng "_" để biểu thị các biến và phương thức riêng tư không? Có lẽ trăn nên dứt khoát có công khai và riêng tư không? Mục đích chính của chúng là cho bạn biết API nào bạn nên sử dụng để tương tác với một lớp. Chúng phục vụ như một tài liệu cho bạn biết sử dụng các phương pháp này và không sử dụng các phương pháp đó. Chúng không phải là "giả vờ bảo mật", chúng là tài liệu API, thậm chí IDE có thể sử dụng để hướng dẫn bạn!
PedroD

19
Đây là một câu trả lời tốt và lý luận của bạn chắc chắn là hợp lệ, nhưng tôi không đồng ý với một khía cạnh. Mục đích của sửa đổi truy cập chưa bao giờ được bảo mật . Thay vào đó, chúng là một phương tiện phân định rõ ràng (và ở mức độ lớn, thi hành) những phần nào của một lớp được coi là nội bộ và được tiếp xúc với người dùng bên ngoài của lớp đó. Các quy ước (văn hóa) chắc chắn là một sự thay thế hợp lệ cho các công cụ sửa đổi truy cập và cả hai phương pháp đều có ưu và nhược điểm của chúng, nhưng nó gây hiểu lầm cho mục đích rằng các công cụ sửa đổi truy cập cấp ngôn ngữ được dự định theo bất kỳ cách nào là "an toàn" theo nghĩa thông thường của từ.
devios1

159

Các biến riêng tư trong python ít nhiều là một hack: trình thông dịch cố ý đổi tên biến.

class A:
    def __init__(self):
        self.__var = 123
    def printVar(self):
        print self.__var

Bây giờ, nếu bạn cố gắng truy cập __varbên ngoài định nghĩa lớp, nó sẽ thất bại:

 >>>x = A()
 >>>x.__var # this will return error: "A has no attribute __var"

 >>>x.printVar() # this gives back 123

Nhưng bạn có thể dễ dàng thoát khỏi điều này:

 >>>x.__dict__ # this will show everything that is contained in object x
               # which in this case is something like {'_A__var' : 123}

 >>>x._A__var = 456 # you now know the masked name of private variables
 >>>x.printVar() # this gives back 456

Bạn có thể biết rằng các phương thức trong OOP được gọi như thế này : x.printVar() => A.printVar(x), nếu A.printVar()có thể truy cập một số trường trong đó x, thì trường này cũng có thể được truy cập bên ngoài A.printVar() ... sau khi tất cả, các hàm được tạo để tái sử dụng, không có sức mạnh đặc biệt nào được đưa ra cho các câu lệnh bên trong.

Trò chơi là khác nhau khi có một trình biên dịch liên quan ( quyền riêng tư là một khái niệm cấp trình biên dịch ). Nó biết về định nghĩa lớp với các sửa đổi kiểm soát truy cập để nó có thể lỗi nếu các quy tắc không được tuân theo tại thời điểm biên dịch


3
Nói

2
Tôi tự hỏi liệu PHP có cái gì đó tương tự với các biến riêng tư ngớ ngẩn của nó không - vì các biến riêng tư không thực sự có ý nghĩa trong ngôn ngữ được giải thích - Ý tôi là nó có thể tối ưu hóa gì khi biết biến x là riêng tư, nếu nó không được biên dịch?
NoBugs

1
Làm thế nào chúng ta có thể ngẫu nhiên mô hình của các biến riêng tư?
crisron 7/2/2016

@crisron cùng một câu hỏi
IANS

5
@watashiSHUN "nói ngắn gọn, đây không phải là đóng gói" => đúng vậy. Đóng gói là về việc chỉ sử dụng API công cộng để mã máy khách được bảo vệ khỏi các thay đổi triển khai. Các quy ước đặt tên là một cách hoàn toàn hợp lệ để cho biết API là gì và triển khai là gì và vấn đề là nó chỉ hoạt động.
bruno Desthuilliers

30

Như được đề cập chính xác bởi nhiều ý kiến ​​ở trên, chúng ta đừng quên mục tiêu chính của Công cụ sửa đổi truy cập: Để giúp người dùng mã hiểu những gì được cho là thay đổi và những gì được cho là không nên thay đổi. Khi bạn nhìn thấy một lĩnh vực riêng tư, bạn không phải loay hoay với nó. Vì vậy, nó chủ yếu là đường cú pháp dễ dàng đạt được trong Python bởi _ và __.


4
Tôi nghĩ rằng đây là một điểm quan trọng như bất kỳ. Khi gỡ lỗi mã (tôi biết, tôi là một kẻ yếu để giới thiệu các lỗi), biết các lớp nào có thể thay đổi một biến thành viên đơn giản hóa quá trình gỡ lỗi. Ít nhất, nếu biến được bảo vệ bởi một số phạm vi. Một khái niệm tương tự là các hàm const trong C ++. Tôi biết rằng các biến thành viên không thay đổi trong đó và vì vậy tôi thậm chí không xem phương thức đó là nguyên nhân tiềm năng của cài đặt biến xấu. Mặc dù nó có thể thực hiện phát triển tiếp theo các tiện ích mở rộng lớp / thêm tính năng, nhưng việc giới hạn khả năng hiển thị của mã giúp việc gỡ lỗi dễ dàng hơn.
MrMas

18

Có một biến thể của các biến riêng tư trong quy ước gạch dưới.

In [5]: class Test(object):
   ...:     def __private_method(self):
   ...:         return "Boo"
   ...:     def public_method(self):
   ...:         return self.__private_method()
   ...:     

In [6]: x = Test()

In [7]: x.public_method()
Out[7]: 'Boo'

In [8]: x.__private_method()
---------------------------------------------------------------------------
AttributeError                            Traceback (most recent call last)
<ipython-input-8-fa17ce05d8bc> in <module>()
----> 1 x.__private_method()

AttributeError: 'Test' object has no attribute '__private_method'

Có một số khác biệt tinh tế, nhưng vì lợi ích của mô hình lập trình thuần túy về ý thức hệ, nó đủ tốt.

Có những ví dụ về các nhà trang trí @private thực hiện chặt chẽ hơn khái niệm này, nhưng YMMV. Có thể cho rằng người ta cũng có thể viết một định nghĩa lớp sử dụng meta


14
Tôi nhận ra điều này là khá muộn cho bữa tiệc nhưng liên kết này hiển thị trên google khi giải quyết vấn đề. Điều này không nói lên toàn bộ câu chuyện. __xnhư một biến bên trong lớp Athực sự được trình biên dịch viết lại _A__x, nó vẫn không hoàn toàn riêng tư và vẫn có thể được truy cập.
Zorf

1
Tất nhiên, nếu tôi thấy một biến có tên _A__x, tôi sẽ không chạm vào nó. Nó có thể truyền nhiễm. Tôi sẽ chạy trốn khỏi nó.
Mateen Ulhaq

RIght chắc chắn nó không phải là một tư nhân thực sự . Nhưng lý do nguyên tắc cho riêng tư được thi hành cứng trong C ++ và Java (v.v.), tối ưu hóa trình biên dịch, không thực sự tồn tại trong Python, do đó, riêng tư theo quy ước là đủ tốt. Quy ước Python nói chung là nó tin tưởng rằng bạn sẽ cư xử với chính mình mà không cần giám sát. (Và đó là một cái bẫy người mới, nhưng bạn biết đấy, hãy suy nghĩ kỹ về thiết kế và tiêu dùng của lớp)
Shayne

14

"Trong java, chúng tôi đã được dạy về các biến công khai / riêng tư / được bảo vệ"

"Tại sao điều đó không bắt buộc ở trăn?"

Vì lý do tương tự, nó không bắt buộc trong Java.

Bạn có thể sử dụng miễn phí - hoặc không sử dụng privateprotected.

Là một lập trình viên Python và Java, tôi đã thấy điều đó privateprotectedlà những khái niệm thiết kế rất, rất quan trọng. Nhưng như một vấn đề thực tế, trong hàng chục ngàn dòng Java và Python, tôi chưa bao giờ thực sự sử dụng privatehay protected.

Tại sao không?

Đây là câu hỏi của tôi "được bảo vệ từ ai?"

Các lập trình viên khác trong nhóm của tôi? Họ có nguồn. Không được bảo vệ có nghĩa là gì khi họ có thể thay đổi nó?

Các lập trình viên khác trong các đội khác? Họ làm việc cho cùng một công ty. Họ có thể - với một cuộc gọi điện thoại - lấy nguồn.

Khách hàng? Đó là chương trình làm việc cho thuê (nói chung). Các khách hàng (nói chung) sở hữu mã.

Vì vậy, ai - chính xác - tôi đang bảo vệ nó khỏi?


119
-1: Tôi đồng ý với porculus. Đây không phải là về việc cấm truy cập hoặc che giấu điều gì đó, mà là về tài liệu API ẩn . Các nhà phát triển cũng như trình biên dịch / trình thông dịch / kiểm tra mã dễ dàng xem các thành viên nào được khuyến nghị sử dụng và những thành viên nào không nên chạm vào (hoặc ít nhất là cẩn thận). Trong hầu hết các trường hợp, nó sẽ là một mớ hỗn độn khủng khiếp nếu tất cả các thành viên của một lớp hoặc mô-đun là công khai. Hãy xem xét sự khác biệt của các thành viên tư nhân / được bảo vệ / công khai như một dịch vụ, nói rằng: "Này, những thành viên này rất quan trọng trong khi những thành viên đó được sử dụng nội bộ và có thể không hữu ích cho bạn."
Oben Sonne

7
@ S.Lott: Tôi đồng ý rằng các tài liệu API có mức độ ưu tiên cao hơn và thường là cách duy nhất để truyền đạt các mục đích sử dụng của API. Nhưng đôi khi tên thành viên và khả năng hiển thị (về mặt riêng tư / công khai) đủ để tự nói. Ngoài ra, tôi thấy quan điểm của bạn rằng ý tưởng về tài liệu ngầm không hoạt động tốt trong các trình soạn thảo khi kiểm tra API nhưng nó thực sự hữu ích trong IDE khi hoàn thành mã. Giả sử bạn đã đọc các tài liệu API cách đây một thời gian, nó sẽ giúp bạn nhớ cách sử dụng một lớp. Mọi thứ sẽ không hoạt động thông minh nếu không có sự phân biệt giữa các thành viên tư nhân và công cộng.
Oben Sonne

21
Cuối buổi thảo luận, nhưng mọi thứ mà porculus và Oben đang yêu cầu ở đây đều được xử lý một cách hoàn hảo bằng quy ước "tiền tố với một dấu gạch dưới" (và không có tác hại mà việc thực thi trình biên dịch của quy ước đó có thể gây ra)
ncoghlan

38
@ S.Lott Tôi không phải là một con trăn, vì vậy tôi sẽ không bình luận từ quan điểm đó. Tuy nhiên, là một nhà phát triển java, đây thực sự là một lời khuyên kinh khủng. -1
dbyrne

11
Ồ Bạn hoàn toàn bỏ lỡ quan điểm, bạn đưa ra một lời khuyên rất tệ, bạn xúc phạm bất cứ ai không đồng ý với bạn về điểm này, nhưng bạn vẫn nhận được huy hiệu và hơn 1000 điểm danh tiếng cho "câu trả lời" này.
Eric Duminil

12

Như đã đề cập trước đó, bạn có thể chỉ ra rằng một biến hoặc phương thức là riêng tư bằng cách thêm tiền tố vào dấu gạch dưới. Nếu bạn không cảm thấy như thế là đủ, bạn luôn có thể sử dụng propertytrang trí. Đây là một ví dụ:

class Foo:

    def __init__(self, bar):
        self._bar = bar

    @property
    def bar(self):
        """Getter for '_bar'."""
        return self._bar

Theo cách này, ai đó hoặc một cái gì đó tham chiếu barthực sự đang tham chiếu giá trị trả về của barhàm chứ không phải là chính biến đó, và do đó nó có thể được truy cập nhưng không thay đổi. Tuy nhiên, nếu ai đó thực sự muốn, họ có thể chỉ cần sử dụng _barvà gán một giá trị mới cho nó. Không có cách nào chắc chắn để ngăn người khác truy cập vào các biến và phương thức mà bạn muốn ẩn, như đã nói nhiều lần. Tuy nhiên, sử dụng propertylà thông điệp rõ ràng nhất bạn có thể gửi rằng một biến không được chỉnh sửa. propertycũng có thể được sử dụng cho các đường dẫn truy cập getter / setter / deleter phức tạp hơn, như được giải thích ở đây: https://docs.python.org/3/l Library / fiances.html # property


Django cũng đánh giá cao điều này.
babygame0ver

10

Python có hỗ trợ hạn chế cho các định danh riêng, thông qua một tính năng tự động thêm tên lớp cho bất kỳ định danh nào bắt đầu bằng hai dấu gạch dưới. Điều này là minh bạch đối với lập trình viên, đối với hầu hết các phần, nhưng hiệu quả ròng là bất kỳ biến nào được đặt tên theo cách này đều có thể được sử dụng làm biến riêng.

Xem ở đây để biết thêm về điều đó.

Nói chung, việc triển khai hướng đối tượng của Python hơi thô sơ so với các ngôn ngữ khác. Nhưng tôi thực sự thích điều này. Đó là một cách thực hiện rất đơn giản về mặt khái niệm và phù hợp với phong cách năng động của ngôn ngữ.


Vâng. Vẻ đẹp là, khả năng lập trình siêu dữ liệu của python có nghĩa là bạn thực sự có thể thực hiện các công cụ ưa thích nếu bạn muốn (Và có các thư viện triển khai các trang trí và công cụ @ private / @ bảo vệ / vv. Tôi thậm chí còn thấy một thư viện làm mờ các lớp nguyên mẫu kiểu JS không có lý do chính đáng nào cả), nhưng trong thực tế, điều đó không cần thiết .. Tôi ghét ghét "python / js / anything is a lisp" bởi vì nó gần như không bao giờ đúng, nhưng python chia sẻ các chương trình lập trình siêu hình kết hợp với cú pháp đơn giản 'với ngôn ngữ đó
Shayne

8

Lần duy nhất tôi từng sử dụng các biến riêng là khi tôi cần làm những việc khác khi viết hoặc đọc từ biến đó và do đó tôi cần phải sử dụng một setter và / hoặc getter.

Một lần nữa điều này đi vào văn hóa, như đã nêu. Tôi đã làm việc trên các dự án trong đó việc đọc và viết các biến lớp khác là miễn phí cho tất cả. Khi một triển khai bị phản đối, phải mất nhiều thời gian hơn để xác định tất cả các đường dẫn mã đã sử dụng chức năng đó. Khi việc sử dụng setters và getters bị ép buộc, một câu lệnh gỡ lỗi có thể dễ dàng được viết để xác định rằng phương thức không dùng nữa đã được gọi và đường dẫn mã gọi nó.

Khi bạn đang ở trong một dự án nơi bất kỳ ai cũng có thể viết một phần mở rộng, thông báo cho người dùng về các phương thức không dùng nữa sẽ biến mất trong một vài bản phát hành, do đó rất quan trọng để giữ cho sự phá vỡ mô-đun ở mức tối thiểu khi nâng cấp.

Vì vậy, câu trả lời của tôi là; nếu bạn và đồng nghiệp của bạn duy trì một bộ mã đơn giản thì việc bảo vệ các biến lớp không phải lúc nào cũng cần thiết. Nếu bạn đang viết một hệ thống có thể mở rộng thì nó trở nên cấp thiết khi các thay đổi đối với lõi được thực hiện cần phải được bắt bởi tất cả các tiện ích mở rộng sử dụng mã.


8

Xin lỗi các bạn đã "hồi sinh" chủ đề, nhưng, tôi hy vọng điều này sẽ giúp được ai đó:

Trong Python3 nếu bạn chỉ muốn "đóng gói" các thuộc tính lớp, như trong Java, bạn có thể làm điều tương tự như thế này:

class Simple:
    def __init__(self, str):
        print("inside the simple constructor")
        self.__s = str

    def show(self):
        print(self.__s)

    def showMsg(self, msg):
        print(msg + ':', self.show())

Để khởi tạo điều này làm:

ss = Simple("lol")
ss.show()

Lưu ý rằng: print(ss.__s)sẽ ném một lỗi.

Trong thực tế, Python3 sẽ làm xáo trộn tên thuộc tính toàn cầu. Biến nó như một thuộc tính "riêng tư", giống như trong Java. Tên thuộc tính vẫn là toàn cục, nhưng theo cách không thể truy cập, giống như một thuộc tính riêng trong các ngôn ngữ khác.

Nhưng đừng sợ nó. Nó không thành vấn đề. Nó làm công việc quá. ;)


2
điều này đã tồn tại từ Python 1.5.2 IIRC và nó vẫn không ngăn truy cập thuộc tính thông qua tên được đọc sai.
bruno Desthuilliers

7

khái niệm riêng tư và được bảo vệ là rất quan trọng. Nhưng python - chỉ là một công cụ để tạo mẫu và phát triển nhanh chóng với các nguồn lực hạn chế có sẵn để phát triển, đó là lý do tại sao một số cấp độ bảo vệ không quá nghiêm ngặt theo sau python. Bạn có thể sử dụng "__" trong thành viên lớp, nó hoạt động đúng, nhưng trông không đủ tốt - mỗi quyền truy cập vào trường như vậy có chứa các ký tự này.

Ngoài ra, bạn có thể nhận thấy rằng khái niệm OOP python không hoàn hảo, smaltalk hoặc ruby ​​gần hơn với khái niệm OOP thuần túy. Ngay cả C # hoặc Java cũng gần hơn.

Python là công cụ rất tốt. Nhưng nó là ngôn ngữ OOP đơn giản hóa. Cú pháp đơn giản và khái niệm đơn giản. Mục tiêu chính của sự tồn tại của python là mang đến cho các nhà phát triển khả năng viết mã dễ đọc với mức độ trừu tượng cao một cách rất nhanh.


Phía sau Private và Protected rất quan trọng là trong các ngôn ngữ được biên dịch tĩnh, trình biên dịch có thể tạo các cuộc gọi chuyển hướng đến phương thức riêng tư, nhưng phải dựa vào bảng tra cứu cho các phương thức công khai. Thiis đơn giản không phải là một vấn đề với các ngôn ngữ động. Cuối cùng, các ngôn ngữ như C ++ có ý nghĩa đối với kế thừa và giải quyết phương thức. Python và Ruby có các triển khai OO rất giống nhau, vì vậy việc so sánh là vô nghĩa. Smalltalk thực sự không có khái niệm về tin nhắn công cộng / riêng tư. Bạn có thể thêm riêng tư dưới dạng danh mục, nhưng hoàn toàn là tư vấn.
Shayne

Để tiếp tục khẳng định của tôi. Quan điểm về vệ sinh mã hóa, vâng, chúng rất quan trọng đối với việc đóng gói, nhưng nó không cần thiết cho nó, và vì vậy các nhà trang trí @private (v.v.) khuyên nhiều hơn bất cứ điều gì, nhưng vì riêng tư / công cộng không có gì hữu ích để tối ưu hóa trong ngôn ngữ không tĩnh, ngôn ngữ này không được triển khai ở mức độ sâu như ngôn ngữ được biên dịch như java hoặc c
Shayne

4

Python không có bất kỳ biến riêng tư nào như C ++ hay Java. Bạn cũng có thể truy cập bất kỳ biến thành viên nào nếu muốn. Tuy nhiên, bạn không cần các biến riêng tư trong Python, vì trong Python, việc hiển thị các biến thành viên lớp của bạn không phải là xấu. Nếu bạn có nhu cầu đóng gói một biến thành viên, bạn có thể thực hiện việc này bằng cách sử dụng "@property" sau này mà không phá vỡ mã máy khách hiện tại.

Trong python, dấu gạch dưới đơn "_" được sử dụng để chỉ ra rằng một phương thức hoặc biến không được coi là một phần của api công khai của một lớp và phần này của api có thể thay đổi giữa các phiên bản khác nhau. Bạn có thể sử dụng các phương thức / biến này, nhưng mã của bạn có thể bị hỏng, nếu bạn sử dụng phiên bản mới hơn của lớp này.

Dấu gạch dưới kép "__" không có nghĩa là "biến riêng". Bạn sử dụng nó để định nghĩa các biến là "lớp cục bộ" và không thể dễ dàng bị các lớp con vượt qua. Nó mang tên biến.

Ví dụ:

class A(object):
    def __init__(self):
        self.__foobar = None # will be automatically mangled to self._A__foobar

class B(A):
    def __init__(self):
        self.__foobar = 1 # will be automatically mangled to self._B__foobar

tên của mình Vì vậy, mỗi lớp con có thể định nghĩa biến __foobar của riêng nó mà không ghi đè (các) biến cha mẹ của nó. Nhưng không có gì ngăn cản bạn truy cập các biến bắt đầu bằng dấu gạch dưới kép. Tuy nhiên, xáo trộn tên ngăn bạn gọi các biến / phương thức này một cách tình cờ.

Tôi thực sự khuyên bạn nên xem Raymond Hettingers nói "Bộ công cụ phát triển lớp Pythons" từ Pycon 2013 (nên có sẵn trên Youtube), đưa ra một ví dụ tốt về lý do và cách bạn nên sử dụng các biến đối tượng @property và "__".


Tôi sẽ kiểm tra cuộc nói chuyện đó. Đây có phải là @propertymột phần của Python tiêu chuẩn hay nó dành riêng cho IDE?
bballdave025

Đó là một phần của tiêu chuẩn kể từ python 2.6. Nếu bạn nên sử dụng phiên bản cũ hơn, vẫn có khả năng sử dụng propertychức năng dựng sẵn, có sẵn kể từ python 2.2
Hatatister

0

Trên thực tế, bạn có thể mô phỏng một C#getter và setter bằng thủ thuật đơn giản này:

class Screen(object):

    def getter_setter_y(self, y, get=True):
        if get is True:
            Screen.getter_setter_y.value = y
        else:
            return Screen.getter_setter_y.value

     def getter_setter_x(self, x, get=True):
         if get is True:
             Screen.getter_setter_x.value = x
         else:
             return Screen.getter_setter_x.value

Sau đó sử dụng nó tương tự như trong C#:

scr = Screen()
scr.getter_setter_x(100)
value =  scr.getter_setter_x(0, get=False)
print (value)

Đó chỉ là khai báo một biến cục bộ tĩnh trong một hàm sẽ đóng vai trò get / set, vì đó là cách duy nhất để chia sẻ một biến thông qua các phương thức get và set, mà không làm cho nó trở thành toàn cầu cho một lớp hoặc tệp.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.