Python có gõ mạnh không?


234

Tôi đã đi qua các liên kết nói rằng Python là một ngôn ngữ được gõ mạnh.

Tuy nhiên, tôi nghĩ bằng các ngôn ngữ được gõ mạnh, bạn không thể làm điều này:

bob = 1
bob = "bob"

Tôi nghĩ rằng một ngôn ngữ được gõ mạnh mẽ không chấp nhận thay đổi kiểu vào thời gian chạy. Có lẽ tôi đã có một định nghĩa sai (hoặc quá đơn giản) về các loại mạnh / yếu.

Vì vậy, Python là một ngôn ngữ gõ mạnh hay yếu?

Câu trả lời:


358

Python mạnh mẽ, năng động gõ.

  • Gõ mạnh có nghĩa là loại giá trị không thay đổi theo những cách không mong muốn. Một chuỗi chỉ chứa các chữ số không kỳ diệu trở thành một số, như có thể xảy ra trong Perl. Mỗi thay đổi của loại yêu cầu một chuyển đổi rõ ràng.
  • Gõ động có nghĩa là các đối tượng thời gian chạy (giá trị) có một kiểu, trái ngược với kiểu gõ tĩnh trong đó các biến có một kiểu.

Như ví dụ của bạn

bob = 1
bob = "bob"

Điều này hoạt động vì biến không có một loại; nó có thể đặt tên cho bất kỳ đối tượng nào. Sau đó bob=1, bạn sẽ thấy rằng type(bob)trả lại int, nhưng sau bob="bob"đó, nó sẽ trả lại str. (Lưu ý rằng đó typelà một hàm thông thường, do đó, nó đánh giá đối số của nó, sau đó trả về loại giá trị.)

Tương phản điều này với các phương ngữ cũ của C, vốn được đánh máy yếu, được gõ tĩnh, do đó các con trỏ và số nguyên có thể thay thế cho nhau. (ISO C hiện đại yêu cầu chuyển đổi trong nhiều trường hợp, nhưng trình biên dịch của tôi vẫn khoan dung về điều này theo mặc định.)

Tôi phải thêm rằng kiểu gõ mạnh so với yếu là liên tục hơn là lựa chọn boolean. C ++ có kiểu gõ mạnh hơn C (yêu cầu nhiều chuyển đổi hơn), nhưng hệ thống loại có thể được lật đổ bằng cách sử dụng phôi con trỏ.

Sức mạnh của hệ thống loại trong một ngôn ngữ động như Python thực sự được xác định bằng cách các nguyên hàm và chức năng thư viện của nó phản ứng với các loại khác nhau. Ví dụ, +bị quá tải để nó hoạt động trên hai số hoặc hai chuỗi, nhưng không phải là một chuỗi và một số. Đây là một lựa chọn thiết kế được thực hiện khi +được triển khai, nhưng không thực sự cần thiết theo ngữ nghĩa của ngôn ngữ. Trong thực tế, khi bạn quá tải +trên một loại tùy chỉnh, bạn có thể làm cho nó hoàn toàn chuyển đổi bất cứ thứ gì thành một số:

def to_number(x):
    """Try to convert function argument to float-type object."""
    try: 
        return float(x) 
    except (TypeError, ValueError): 
        return 0 

class Foo:
    def __init__(self, number): 
        self.number = number

    def __add__(self, other):
        return self.number + to_number(other)

Sơ thẩm của lớp Foocó thể được thêm vào các đối tượng khác:

>>> a = Foo(42)
>>> a + "1"
43.0
>>> a + Foo
42
>>> a + 1
43.0
>>> a + None
42

Nhận xét rằng mặc dù đã gõ mạnh Python là hoàn toàn tốt với thêm đối tượng thuộc loại intfloatvà trả về một đối tượng kiểu float(ví dụ, int(42) + float(1)lợi nhuận 43.0). Mặt khác, do sự không phù hợp giữa các loại Haskell sẽ khiếu nại nếu một người cố gắng làm như sau (42 :: Integer) + (1 :: Float). Điều này làm cho Haskell trở thành một ngôn ngữ được gõ chính xác, trong đó các loại hoàn toàn rời rạc và chỉ có thể có một hình thức quá tải được kiểm soát thông qua các lớp loại.


18
Một ví dụ tôi không thấy thường xuyên nhưng tôi nghĩ rất quan trọng để chỉ ra rằng Python không được gõ hoàn toàn mạnh mẽ, là tất cả những điều đánh giá về boolean: docs.python.org/release/2.5.2/lib/truth.html
gsingh2011

25
Không chắc lắm nếu đây là một ví dụ ngược lại: Mọi thứ có thể đánh giá thành một boolean, nhưng chúng không đột nhiên "trở thành" một boolean. Nó gần như là ai đó ngầm gọi một cái gì đó như as_boolean (<value>), không giống với loại đối tượng tự thay đổi, phải không?
joustndel

15
Tính trung thực trong bối cảnh boolean không phải là một ví dụ, bởi vì không có gì thực sự được chuyển đổi thành Truehoặc False. Nhưng còn khuyến mãi số thì sao? 1.0 + 2hoạt động tốt như trong Python cũng như trong Perl hoặc C, mặc dù "1.0" + 2không. Tôi đồng ý với @jbrendel rằng đây thực sự không phải là một chuyển đổi ngầm định, nó chỉ làm quá tải chương trình giáo dục nhưng theo nghĩa tương tự, Perl cũng không thực hiện bất kỳ chuyển đổi ngầm nào. Nếu các hàm không khai báo các loại tham số, sẽ không có chuyển đổi ngầm nào xảy ra.
abarnert

13
Một cách tốt hơn để suy nghĩ về việc gõ mạnh là kiểu đó quan trọng khi thực hiện các thao tác trên một biến. Nếu loại không như mong đợi, một ngôn ngữ phàn nàn sẽ được gõ mạnh (python / java) và ngôn ngữ không được gõ yếu (javascript) Ngôn ngữ được nhập động (python) là những ngôn ngữ cho phép loại biến thay đổi tại thời gian chạy trong khi các ngôn ngữ gõ tĩnh (java) không cho phép điều này một khi một biến được khai báo.
kashif

2
@ gsingh2011 Sự thật là hữu ích và không phải tự gõ yếu , nhưng một sự tình cờ if isValid(value) - 1có thể bị rò rỉ. Boolean được ép thành số nguyên, sau đó được đánh giá là giá trị trung thực. False - 1trở thành sự thật và True - 1trở nên giả dối , dẫn đến một lỗi hai lớp khó xử đáng xấu hổ để gỡ lỗi. Theo nghĩa này, trăn chủ yếu được đánh máy mạnh mẽ; kiểu ép buộc thường không gây ra lỗi logic.
Aaron3468

57

Có một số vấn đề quan trọng mà tôi nghĩ rằng tất cả các câu trả lời hiện có đã bỏ lỡ.


Gõ yếu có nghĩa là cho phép truy cập vào các đại diện cơ bản. Trong C, tôi có thể tạo một con trỏ tới các ký tự, sau đó báo cho trình biên dịch tôi muốn sử dụng nó làm con trỏ tới các số nguyên:

char sz[] = "abcdefg";
int *i = (int *)sz;

Trên nền tảng endian nhỏ với số nguyên 32 bit, điều này tạo ithành một mảng các số 0x646362610x00676665. Trong thực tế, bạn thậm chí có thể tự chuyển con trỏ tới số nguyên (có kích thước phù hợp):

intptr_t i = (intptr_t)&sz;

Và tất nhiên điều này có nghĩa là tôi có thể ghi đè lên bộ nhớ ở bất cứ đâu trong hệ thống. *

char *spam = (char *)0x12345678
spam[0] = 0;

* Tất nhiên hệ điều hành hiện đại sử dụng bộ nhớ ảo và bảo vệ trang để tôi chỉ có thể ghi đè lên bộ nhớ của chính mình, nhưng không có gì về chính C cung cấp sự bảo vệ như vậy, như bất kỳ ai từng mã hóa, nói, Classic Mac OS hoặc Win16 đều có thể cho bạn biết.

Lisp truyền thống cho phép các loại tin tặc tương tự; trên một số nền tảng, các ô nổi hai từ và các ô khuyết điểm là cùng loại và bạn có thể chuyển một hàm này sang một hàm khác và nó sẽ "hoạt động".

Hầu hết các ngôn ngữ ngày nay không quá yếu như C và Lisp, nhưng nhiều ngôn ngữ vẫn còn hơi rò rỉ. Ví dụ: bất kỳ ngôn ngữ OO nào có "downcast" không được kiểm tra, * đó là một loại rò rỉ: về cơ bản bạn đang nói với trình biên dịch "Tôi biết tôi không cung cấp cho bạn đủ thông tin để biết điều này an toàn, nhưng tôi khá chắc chắn đó là, "khi toàn bộ quan điểm của một hệ thống kiểu là trình biên dịch luôn có đủ thông tin để biết những gì an toàn.

* Một downcast được kiểm tra không làm cho hệ thống loại ngôn ngữ trở nên yếu hơn chỉ vì nó chuyển kiểm tra sang thời gian chạy. Nếu đúng như vậy, thì tính đa hình của kiểu con (còn gọi là các hàm gọi ảo hoặc hoàn toàn động) sẽ là vi phạm tương tự hệ thống loại và tôi không nghĩ có ai muốn nói điều đó.

Rất ít ngôn ngữ "scripting" yếu theo nghĩa này. Ngay cả trong Perl hoặc Tcl, bạn không thể lấy một chuỗi và chỉ diễn giải các byte của nó là một số nguyên. * Nhưng đáng chú ý là trong CPython (và tương tự đối với nhiều trình thông dịch khác cho nhiều ngôn ngữ), nếu bạn thực sự kiên trì, bạn có thể sử dụng ctypesđể tải lên libpython, truyền vật thể idlên a POINTER(Py_Object)và buộc hệ thống loại bị rò rỉ. Việc này có làm cho hệ thống loại yếu hay không phụ thuộc vào các trường hợp sử dụng của bạn, nếu bạn đang cố gắng thực hiện một hộp cát thực thi bị hạn chế bằng ngôn ngữ để đảm bảo an ninh, bạn phải đối phó với các loại thoát này.

* Bạn có thể sử dụng một hàm như struct.unpackđể đọc các byte và xây dựng một int mới từ "cách C sẽ biểu diễn các byte này", nhưng rõ ràng điều đó không bị rò rỉ; thậm chí Haskell cho phép điều đó.


Trong khi đó, chuyển đổi ngầm thực sự là một điều khác biệt với một hệ thống loại yếu hoặc rò rỉ.

Mọi ngôn ngữ, thậm chí Haskell, đều có chức năng chuyển đổi một số nguyên thành chuỗi hoặc dấu phẩy. Nhưng một số ngôn ngữ sẽ tự động thực hiện một số chuyển đổi đó cho bạn, ví dụ như trong C, nếu bạn gọi một hàm muốn a floatvà bạn chuyển nó vào int, nó sẽ được chuyển đổi cho bạn. Điều này chắc chắn có thể dẫn đến các lỗi với, ví dụ, tràn bất ngờ, nhưng chúng không phải là các loại lỗi bạn gặp phải từ một hệ thống loại yếu. Và C không thực sự yếu hơn ở đây; bạn có thể thêm một int và một float trong Haskell, hoặc thậm chí ghép một float vào một chuỗi, bạn chỉ cần làm điều đó rõ ràng hơn.

Và với các ngôn ngữ năng động, điều này khá âm u. Không có thứ gọi là "một hàm muốn nổi" trong Python hoặc Perl. Nhưng có những hàm quá tải làm những việc khác nhau với các loại khác nhau và có một cảm giác trực quan mạnh mẽ, ví dụ, thêm một chuỗi vào một thứ khác là "một hàm muốn một chuỗi". Theo nghĩa đó, Perl, Tcl và JavaScript dường như thực hiện rất nhiều chuyển đổi ngầm định ( "a" + 1mang lại cho bạn "a1"), trong khi Python làm ít hơn rất nhiều ( "a" + 1đưa ra một ngoại lệ, nhưng 1.0 + 1cung cấp cho bạn 2.0*). Thật khó để đưa ý nghĩa đó vào các thuật ngữ chính thức tại sao không nên có +một chuỗi lấy một chuỗi và một int, khi rõ ràng có các hàm khác, như lập chỉ mục, phải không?

* Trên thực tế, trong Python hiện đại, điều đó có thể được giải thích dưới dạng phân nhóm OO, vì isinstance(2, numbers.Real)nó là đúng. Tôi không nghĩ có bất kỳ ý nghĩa nào trong đó 2là một thể hiện của loại chuỗi trong Perl hoặc JavaScript, mặc dù trong Tcl, thực tế là như vậy, vì mọi thứ đều là một thể hiện của chuỗi.


Cuối cùng, có một định nghĩa khác, hoàn toàn trực giao, định nghĩa về kiểu gõ "mạnh" so với "yếu", trong đó "mạnh" có nghĩa là mạnh mẽ / linh hoạt / biểu cảm.

Ví dụ, Haskell cho phép bạn xác định loại đó là số, chuỗi, danh sách loại này hoặc bản đồ từ chuỗi sang loại này, đây là một cách hoàn hảo để thể hiện bất cứ điều gì có thể được giải mã từ JSON. Không có cách nào để định nghĩa một kiểu như vậy trong Java. Nhưng ít nhất Java có các kiểu tham số (chung), vì vậy bạn có thể viết một hàm lấy Danh sách T và biết rằng các phần tử thuộc loại T; các ngôn ngữ khác, như Java ban đầu, buộc bạn phải sử dụng Danh sách đối tượng và downcast. Nhưng ít nhất Java cho phép bạn tạo các kiểu mới bằng các phương thức riêng của chúng; C chỉ cho phép bạn tạo cấu trúc. Và BCPL thậm chí không có điều đó. Và như vậy để lắp ráp, trong đó các loại duy nhất là độ dài bit khác nhau.

Vì vậy, theo nghĩa đó, hệ thống loại của Haskell mạnh hơn Java hiện đại, mạnh hơn Java trước đó, mạnh hơn C, mạnh hơn BCPL.

Vậy, Python phù hợp với phổ đó ở đâu? Đó là một chút khó khăn. Trong nhiều trường hợp, gõ vịt cho phép bạn mô phỏng mọi thứ bạn có thể làm trong Haskell, và thậm chí một số điều bạn không thể làm được; chắc chắn, lỗi được bắt gặp trong thời gian chạy thay vì thời gian biên dịch, nhưng chúng vẫn bị bắt. Tuy nhiên, có những trường hợp gõ vịt không đủ. Ví dụ, trong Haskell, bạn có thể nói rằng một danh sách ints trống là danh sách các số nguyên, vì vậy bạn có thể quyết định rằng việc giảm +trên danh sách đó sẽ trả về 0 *; trong Python, một danh sách trống là một danh sách trống; không có thông tin loại nào để giúp bạn quyết định việc giảm bớt +nên làm gì.

* Trên thực tế, Haskell không cho phép bạn làm điều này; nếu bạn gọi hàm giảm không lấy giá trị bắt đầu trong danh sách trống, bạn sẽ gặp lỗi. Nhưng hệ thống loại của nó đủ mạnh để bạn có thể làm việc này và Python thì không.


3
Câu trả lời này thật tuyệt vời! Một sự xấu hổ là nó mòn mỏi quá lâu ở cuối danh sách.
LeoR

1
Chỉ cần một nhận xét nhỏ cho ví dụ C của bạn: char sz[]không phải là một con trỏ tới char, nó là mảng char và trong bài tập, nó phân rã thành con trỏ.
Majkel.mk

39

Bạn đang nhầm lẫn 'gõ mạnh' với 'gõ động' .

Tôi không thể thay đổi loại 1bằng cách thêm chuỗi '12', nhưng tôi có thể chọn loại tôi lưu trữ trong một biến và thay đổi loại đó trong thời gian chạy chương trình.

Đối lập với gõ động là gõ tĩnh; những tuyên bố của các loại biến không thay đổi trong suốt cuộc đời của một chương trình. Đối lập với gõ mạnh là gõ yếu; loại giá trị có thể thay đổi trong suốt vòng đời của chương trình.


Mô tả trong liên kết được gõ mạnh: "Nói chung, một ngôn ngữ được gõ mạnh có quy tắc gõ chặt chẽ hơn trong thời gian biên dịch, ngụ ý rằng lỗi và ngoại lệ có nhiều khả năng xảy ra trong quá trình biên dịch." ngụ ý Python là một ngôn ngữ được gõ yếu ..., wiki có sai không?
Mưa

1
@ s̮̦̩e̝͓c̮͔̞ṛ̖̖e̬̣̦t̸͉̥̳̼: điều đó không ngụ ý gì cả. Python có các quy tắc gõ nghiêm ngặt tại thời gian biên dịch, mỗi đối tượng được tạo chỉ có một loại. Và 'nói chung' không ngụ ý bất cứ điều gì, nó chỉ có nghĩa là Python là một ngoại lệ cho điều đó.
Martijn Pieters

24

Theo wiki Python này bài viết này Python Python vừa được đánh máy vừa mạnh mẽ (cũng cung cấp một lời giải thích tốt).

Có lẽ bạn đang nghĩ về việc gõ tĩnh ngôn ngữ nơi các loại không thể thay đổi trong khi thực hiện chương trình và kiểm tra loại xảy ra trong thời gian biên dịch để phát hiện các lỗi có thể.

Câu hỏi SO này có thể được quan tâm: Ngôn ngữ loại động so với ngôn ngữ loại tĩnh và bài viết Wikipedia này về Hệ thống Loại cung cấp thêm thông tin


18

TLDR;

Kiểu gõ của Python là Dynamic để bạn có thể thay đổi biến chuỗi thành int

x = 'somestring'
x = 50

Gõ Python là Mạnh để bạn không thể hợp nhất các loại:

'foo' + 3 --> TypeError: cannot concatenate 'str' and 'int' objects

Trong Javascript gõ yếu, điều này xảy ra ...

 'foo'+3 = 'foo3'

Về suy luận kiểu

Java buộc bạn phải khai báo rõ ràng các loại đối tượng của bạn

int x = 50

Kotlin sử dụng suy luận để nhận ra đó là mộtint

x = 50

Nhưng vì cả hai ngôn ngữ đều sử dụng loại tĩnh , xkhông thể thay đổi từ một int. Không ngôn ngữ nào cho phép thay đổi năng động như

x = 50
x = 'now a string'

Tôi không biết chi tiết về Javascript nhưng 'x' + 3có thể đang operator+quá tải và thực hiện chuyển đổi loại phía sau hậu trường?
Mưa

3
Dù sao, câu trả lời của bạn thực sự ngắn gọn và dễ hiểu hơn những câu hỏi trên.
Mưa

8

Nó đã được trả lời một vài lần, nhưng Python là một ngôn ngữ được gõ mạnh:

>>> x = 3
>>> y = '4'
>>> print(x+y)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: unsupported operand type(s) for +: 'int' and 'str'

Phần sau trong JavaScript:

var x = 3    
var y = '4'
alert(x + y) //Produces "34"

Đó là sự khác biệt giữa gõ yếu và gõ mạnh. Các loại yếu tự động cố gắng chuyển đổi từ loại này sang loại khác, tùy thuộc vào ngữ cảnh (ví dụ: Perl). Loại mạnh không bao giờ chuyển đổi ngầm.

Sự nhầm lẫn của bạn nằm ở sự hiểu lầm về cách Python liên kết các giá trị với các tên (thường được gọi là các biến).

Trong Python, tên không có loại, vì vậy bạn có thể làm những việc như:

bob = 1
bob = "bob"
bob = "An Ex-Parrot!"

Và tên có thể bị ràng buộc với bất cứ điều gì:

>>> def spam():
...     print("Spam, spam, spam, spam")
...
>>> spam_on_eggs = spam
>>> spam_on_eggs()
Spam, spam, spam, spam

Để đọc thêm:

https://en.wikipedia.org/wiki/Docate_dispatch

và hơi liên quan nhưng nâng cao hơn:

http://effbot.org/zone/call-by-object.htm


1
Vài năm sau - một tài nguyên hữu ích và có liên quan khác: youtu.be/_AEJHKGk9ns
Wayne Werner

Gõ mạnh và gõ yếu không liên quan gì đến loại biểu thức kết quả như 3 + '4'. JavaScript cũng mạnh như Python trong ví dụ này.
qznc

@qznc Javasript mạnh như thế nào? Tôi không tin rằng tôi đã đe dọa rằng nó có liên quan đến loại kết quả, thực sự tôi nói rõ các loại yếu tự động cố gắng chuyển đổi từ loại này sang loại khác .
Wayne Werner

2
@oneloop điều đó không hẳn đúng, chỉ là hành vi kết hợp giữa float và int được xác định rõ và dẫn đến kết quả là float. Bạn có thể làm "3"*4trong python, quá. Kết quả của khóa học, là "3333". Bạn sẽ không nói rằng nó chuyển đổi một trong hai điều. Tất nhiên đó có thể chỉ là tranh luận về ngữ nghĩa.
Wayne Werner

1
@oneloop Điều đó không nhất thiết đúng bởi vì Python tạo floatra sự kết hợp floatintnó chuyển đổi kiểu hoàn toàn. Có một mối quan hệ tự nhiên giữa float và int, và thực sự, loại phép thuật gia truyền phát ra. Tôi cho rằng bạn có thể lập luận rằng Javascript xem xét '3'+4'e'+4cả hai đều là các hoạt động được xác định rõ theo cùng cách mà Python coi 3.0 + 4là được xác định rõ, nhưng tại thời điểm đó thực sự không có loại nào mạnh hay yếu, chỉ (un) được xác định hoạt động.
Wayne Werner

6

Một biến Python lưu trữ một tham chiếu chưa được gắn vào đối tượng đích đại diện cho giá trị.

Bất kỳ thao tác gán nào cũng có nghĩa là gán tham chiếu chưa được đánh dấu cho đối tượng được gán - tức là đối tượng được chia sẻ thông qua tham chiếu gốc và tham chiếu mới (được tính).

Loại giá trị được liên kết với đối tượng đích, không liên quan đến giá trị tham chiếu. Việc kiểm tra loại (mạnh) được thực hiện khi một thao tác có giá trị được thực hiện (thời gian chạy).

Nói cách khác, các biến (về mặt kỹ thuật) không có loại - không có ý nghĩa gì khi nghĩ theo nghĩa của một loại biến nếu muốn chính xác. Nhưng các tài liệu tham khảo được tự động hủy đăng ký và chúng tôi thực sự nghĩ về loại đối tượng mục tiêu.


6

Thuật ngữ "gõ mạnh" không có định nghĩa rõ ràng.

Do đó, việc sử dụng thuật ngữ này phụ thuộc vào người bạn đang nói.

Tôi không xem xét bất kỳ ngôn ngữ nào, trong đó loại biến không được khai báo rõ ràng hoặc được gõ tĩnh để được gõ mạnh.

Gõ mạnh không chỉ loại trừ chuyển đổi (ví dụ: "tự động" chuyển đổi từ số nguyên sang chuỗi). Nó loại trừ sự phân công (nghĩa là thay đổi loại biến).

Nếu đoạn mã sau biên dịch (phiên dịch), ngôn ngữ không được gõ mạnh:

Foo = 1 Foo = "1"

Trong một ngôn ngữ được gõ mạnh, một lập trình viên có thể "dựa vào" một loại.

Ví dụ, nếu một lập trình viên nhìn thấy khai báo,

UINT64 kZarkCount;

và anh ấy hoặc cô ấy biết rằng 20 dòng sau, kZarkCount vẫn là một UINT64 (miễn là nó xảy ra trong cùng một khối) - mà không phải kiểm tra mã can thiệp.


1

Tôi vừa khám phá ra một cách ngắn gọn tuyệt vời để ghi nhớ nó:

Mở rộng động / tĩnh gõ; giá trị gõ mạnh / yếu.


0

Tôi nghĩ rằng, ví dụ đơn giản này bạn nên giải thích sự khác biệt giữa kiểu gõ mạnh và động:

>>> tup = ('1', 1, .1)
>>> for item in tup:
...     type(item)
...
<type 'str'>
<type 'int'>
<type 'float'>
>>>

java:

public static void main(String[] args) {
        int i = 1;
        i = "1"; //will be error
        i = '0.1'; // will be error
    }

Mã python của bạn thể hiện kiểu gõ động trong khi java biểu thị kiểu gõ tĩnh. Một ví dụ tốt hơn sẽ là $ var = '2' + 1 // kết quả là 3
erichlf

@ivleph tôi đồng ý. cũng có thể viết một cái gì đó như thế này: "a" * 3 == "aaa"
Dmitry Zagorulkin

-4
class testme(object):
    ''' A test object '''
    def __init__(self):
        self.y = 0

def f(aTestMe1, aTestMe2):
    return aTestMe1.y + aTestMe2.y




c = testme            #get a variable to the class
c.x = 10              #add an attribute x inital value 10
c.y = 4               #change the default attribute value of y to 4

t = testme()          # declare t to be an instance object of testme
r = testme()          # declare r to be an instance object of testme

t.y = 6               # set t.y to a number
r.y = 7               # set r.y to a number

print(f(r,t))         # call function designed to operate on testme objects

r.y = "I am r.y"      # redefine r.y to be a string

print(f(r,t))         #POW!!!!  not good....

Những điều trên sẽ tạo ra một cơn ác mộng về mã không thể nhầm lẫn trong một hệ thống lớn trong một thời gian dài. Gọi nó là những gì bạn muốn, nhưng khả năng "thay đổi" một cách linh hoạt một loại biến chỉ là một ý tưởng tồi ...

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.