Hướng dẫn can we assign an object to a variable in python? - chúng ta có thể gán một đối tượng cho một biến trong python không?

Mặc dù

>>> dict_a, dict_b, dict_c = {}, {}, {}

là cách đúng đắn để đi trong hầu hết các trường hợp, khi nó nhận được hơn 3 nó trông kỳ lạ

Tưởng tượng

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}

Trong trường hợp tôi muốn khởi tạo nhiều hơn 3 thứ, tôi sử dụng

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]

Trong Python, các biến và cấu trúc dữ liệu không chứa các đối tượng. Thực tế này là cả thường bị bỏ qua và khó khăn để nội tâm hóa.don't contain objects. This fact is both commonly overlooked and tricky to internalize.

Bạn có thể vui vẻ sử dụng Python trong nhiều năm mà không thực sự hiểu các khái niệm dưới đây, nhưng kiến ​​thức này chắc chắn có thể giúp giảm bớt nhiều Gotchas Python thông thường.

Thuật ngữ

Hãy bắt đầu bằng cách giới thiệu một số thuật ngữ. Một vài định nghĩa cuối cùng có thể sẽ không có ý nghĩa cho đến khi chúng tôi xác định chúng chi tiết hơn sau này.

Đối tượng [a.k.a. giá trị]: một "điều". Danh sách, từ điển, chuỗi, số, bộ dữ liệu, chức năng và mô -đun đều là tất cả các đối tượng. "Đối tượng" bất chấp định nghĩa vì mọi thứ là một đối tượng trong Python. [a.k.a. value]: a "thing". Lists, dictionaries, strings, numbers, tuples, functions, and modules are all objects. "Object" defies definition because everything is an object in Python.

Biến [a.k.a. Tên]: Một tên được sử dụng để chỉ một đối tượng. [a.k.a. name]: a name used to refer to an object.

Con trỏ [a.k.a. tham chiếu]: Mô tả nơi một đối tượng sống [thường được hiển thị trực quan dưới dạng mũi tên] [a.k.a. reference]: describes where an object lives [often shown visually as an arrow]

Bình đẳng: liệu hai đối tượng có đại diện cho cùng một dữ liệu: whether two objects represent the same data

Danh tính: Liệu hai con trỏ có đề cập đến cùng một đối tượng: whether two pointers refer to the same object

Những thuật ngữ này được hiểu rõ nhất bởi các mối quan hệ của họ với nhau và đó là mục đích chủ yếu của bài viết này.

Các biến của Python là con trỏ, không phải xô

Các biến trong Python không phải là thùng chứa mọi thứ; Chúng là con trỏ [chúng chỉ vào các đối tượng].pointers [they point to objects].

Từ "con trỏ" nghe có vẻ đáng sợ, nhưng rất nhiều sự khan hiếm đó đến từ các khái niệm liên quan [ví dụ: hội nghị truyền thống] không liên quan trong Python. Trong Python, một con trỏ chỉ đại diện cho kết nối giữa một biến và một đối tượng.the connection between a variable and an objects.

Hãy tưởng tượng các biến sống trong vùng đất thay đổi và các đối tượng sống trong vùng đất đối tượng. Một con trỏ là một mũi tên nhỏ kết nối từng biến với đối tượng mà nó trỏ đến.variables living in variable land and objects living in object land. A pointer is a little arrow that connects each variable to the object it points to.

Sơ đồ trên này đại diện cho trạng thái của quy trình Python của chúng tôi sau khi chạy mã này:

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"

Nếu con trỏ từ làm bạn sợ, hãy sử dụng tham chiếu từ thay thế. Bất cứ khi nào bạn thấy các cụm từ dựa trên con trỏ trong bài viết này, hãy thực hiện một bản dịch tinh thần sang cụm từ dựa trên tham chiếu:pointer scares you, use the word reference instead. Whenever you see pointer-based phrases in this article, do a mental translation to a reference-based phrase:

  • Con trỏ ⇒ tham chiếureference
  • chỉ vào ⇒ tham khảorefer to
  • chỉ vào ⇒ được tham chiếureferenced
  • điểm x đến y ⇒ gây x tham khảo ycause X to refer to Y

Các bài tập hướng một biến vào một đối tượng

Câu lệnh gán chỉ một biến vào một đối tượng. Đó là nó.

Nếu chúng ta chạy mã này:

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"

Trạng thái của các biến và đối tượng của chúng tôi sẽ trông như thế này:

Lưu ý rằng

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
8 và
>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
9 trỏ đến cùng một đối tượng. Nếu chúng ta thay đổi đối tượng đó, cả hai biến dường như sẽ "thấy" sự thay đổi đó:point to the same object. If we change that object, both variables will seem to "see" that change:

>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]

Sự kỳ lạ đó là tất cả do tuyên bố chuyển nhượng này:

Các câu lệnh gán không sao chép bất cứ điều gì: Chúng chỉ chỉ một biến vào một đối tượng. Vì vậy, việc gán một biến cho biến khác chỉ chỉ hai biến vào cùng một đối tượng.points two variables to the same object.

2 loại "thay đổi" trong Python

Python có 2 loại "thay đổi" riêng biệt:

  1. Bài tập thay đổi một biến [nó thay đổi đối tượng mà nó trỏ đến] changes a variable [it changes which object it points to]
  2. Đột biến thay đổi một đối tượng [mà bất kỳ số biến nào có thể chỉ ra] changes an object [which any number of variables might point to]

Từ "thay đổi" thường mơ hồ. Cụm từ "Chúng tôi đã thay đổi

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
0" có thể có nghĩa là "chúng tôi được chỉ định lại
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
0" hoặc nó có thể có nghĩa là "chúng tôi đã biến đổi đối tượng
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
0 điểm thành".

Đột biến thay đổi đối tượng, không phải biến. Nhưng các biến trỏ đến các đối tượng. Vì vậy, nếu một biến khác trỏ đến một đối tượng mà chúng ta vừa đột biến, thì biến khác sẽ phản ánh cùng một thay đổi; Không phải vì biến đã thay đổi mà bởi vì đối tượng nó chỉ ra thay đổi., not variables. But variables point to objects. So if another variable points to an object that we've just mutated, that other variable will reflect the same change; not because the variable changed but because the object it points to changed.

Bình đẳng so sánh các đối tượng và bản sắc so sánh con trỏ

Toán tử

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
3 của Python kiểm tra xem hai đối tượng có đại diện cho cùng một dữ liệu không [a.k.a. Bình đẳng]:represent the same data [a.k.a. equality]:

>>> my_numbers = [2, 1, 3, 4]
>>> your_numbers = [2, 1, 3, 4]
>>> my_numbers == your_numbers
True

Toán tử

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
4 của Python kiểm tra xem hai đối tượng có phải là cùng một đối tượng hay không [nhận dạng a.k.a.]:are the same object [a.k.a. identity]:

>>> my_numbers is your_numbers
False

Các biến

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
5 và
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
6 chỉ vào các đối tượng đại diện cho cùng một dữ liệu, nhưng các đối tượng mà chúng chỉ ra không phải là cùng một đối tượng.objects representing the same data, but the objects they point to are not the same object.

Vì vậy, việc thay đổi một đối tượng không thay đổi khác:

>>> my_numbers[0] = 7
>>> my_numbers == your_numbers
False

Nếu hai biến trỏ đến cùng một đối tượng:

>>> my_numbers_again = my_numbers
>>> my_numbers is my_numbers_again
True

Thay đổi đối tượng Một điểm biến cũng thay đổi đối tượng các điểm khác thành vì cả hai đều trỏ đến cùng một đối tượng:

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
0

Toán tử

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
3 kiểm tra công bằng và toán tử
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
4 kiểm tra nhận dạng. Sự khác biệt này giữa danh tính và bình đẳng tồn tại bởi vì các biến không chứa các đối tượng, chúng chỉ vào các đối tượng.equality and the
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
4 operator checks for identity. This distinction between identity and equality exists because variables don't contain objects, they point to objects.

Trong kiểm tra bình đẳng Python là rất phổ biến và kiểm tra danh tính là rất hiếm.

Không có ngoại lệ cho các đối tượng bất biến

Nhưng chờ đã, sửa đổi một số không thay đổi các biến khác chỉ vào cùng một số, phải không?

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
1

Vâng, sửa đổi một số là không thể trong Python. Các số và chuỗi đều là bất biến, có nghĩa là bạn không thể biến đổi chúng. Bạn không thể thay đổi một đối tượng bất biến.modifying a number is not possible in Python. Numbers and strings are both immutable, meaning you can't mutate them. You cannot change an immutable object.

Vậy còn nhà điều hành

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
9 ở trên thì sao? Đó không phải là một số đột biến? [Nó không.]

Với các đối tượng bất biến, hai câu này tương đương:

Đối với các đối tượng bất biến, các bài tập tăng cường [

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = [11, 18, 29]
>>> name = "Trey"
9,
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
1,
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
2, v.v.] thực hiện một thao tác [trả về một đối tượng mới] và sau đó thực hiện một gán [cho đối tượng mới đó].

Bất kỳ hoạt động nào bạn có thể nghĩ rằng thay đổi một chuỗi hoặc một số thay vì trả về một đối tượng mới. Bất kỳ hoạt động nào trên một đối tượng bất biến luôn trả về một đối tượng mới thay vì sửa đổi bản gốc.returns a new object instead of modifying the original.

Cấu trúc dữ liệu chứa con trỏ

Giống như các biến, cấu trúc dữ liệu không chứa các đối tượng, chúng chứa con trỏ đến các đối tượng.don't contain objects, they contain pointers to objects.

Giả sử chúng tôi lập danh sách danh sách:

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
2

Và sau đó chúng tôi tạo một biến chỉ vào danh sách thứ hai trong danh sách danh sách của chúng tôi:

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
3

Trạng thái của các biến và đối tượng của chúng tôi bây giờ trông như thế này:

Biến

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
3 của chúng tôi chỉ vào cùng một đối tượng với INDEX
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
4 trong danh sách
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
5 của chúng tôi:points to the same object as index
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
4 in our
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
5 list:

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
4

Vì vậy, nếu chúng ta đột biến danh sách mà

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
3 chỉ vào:

Chúng ta sẽ thấy sự thay đổi đó ở cả hai nơi:

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
5

Nó thường nói về các cấu trúc dữ liệu "chứa" các đối tượng, nhưng chúng thực sự chỉ chứa con trỏ đến các đối tượng.

Các đối số chức năng hoạt động giống như các câu lệnh gán

Các cuộc gọi chức năng cũng thực hiện các bài tập.

Nếu bạn đột biến một đối tượng được truyền vào chức năng của bạn, bạn đã đột biến đối tượng gốc:

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
6

Nhưng nếu bạn phân công lại một biến thành một đối tượng khác, đối tượng gốc sẽ không thay đổi:

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
7

Chúng tôi đang phân công lại biến

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
7 ở đây. Việc phân công lại sự thay đổi đối tượng mà biến
>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
7 trỏ đến, nhưng nó không thay đổi đối tượng gốc.

Chúng tôi đã thay đổi một đối tượng trong trường hợp đầu tiên và chúng tôi đã thay đổi một biến trong trường hợp thứ hai.changed an object in the first case and we changed a variable in the second case.

Đây là một ví dụ khác đôi khi bạn sẽ thấy:

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
8

Các phương thức khởi tạo lớp thường sao chép các vòng lặp được cung cấp cho họ bằng cách lập một danh sách mới trong số các mục của họ. Điều này cho phép lớp chấp nhận bất kỳ điều gì có thể lặp lại [không chỉ danh sách] và phân tách sự khác biệt ban đầu từ lớp [sửa đổi các danh sách này sẽ không làm đảo lộn người gọi ban đầu]. Ví dụ trên đã được mượn từ Django.

Đừng biến đổi các đối tượng được truyền vào chức năng của bạn trừ khi người gọi chức năng mong đợi bạn. passed-in to your function unless the function caller expects you to.

Bản sao nông cạn và điều đó thường ổn

Cần sao chép một danh sách trong Python?

>>> a, b, c, d, e, f = {}, {}, {}, {}, {}, {}
9

Bạn có thể gọi phương thức

>>> numbers = [2, 1, 3, 4, 7]
>>> numbers2 = numbers
>>> name = "Trey"
9 [nếu bạn chắc chắn rằng bạn có thể sử dụng được là một danh sách]:

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
0

Hoặc bạn có thể chuyển nó cho hàm tạo

>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]
0 [điều này hoạt động trên bất kỳ điều gì có thể sai]:any iterable]:

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
1

Cả hai kỹ thuật này đều tạo ra một danh sách mới chỉ vào cùng một đối tượng với danh sách ban đầu.points to the same objects as the original list.

Hai danh sách là khác biệt, nhưng các đối tượng trong đó là như nhau:

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
2

Vì các số nguyên [và tất cả các số] là bất biến trong Python, chúng tôi không thực sự quan tâm rằng mỗi danh sách chứa cùng một đối tượng vì dù sao chúng ta cũng không thể thay đổi các đối tượng đó.

Với các đối tượng có thể thay đổi, sự khác biệt này có vấn đề. Điều này tạo ra hai danh sách danh sách mà mỗi danh sách chứa các con trỏ đến cùng ba danh sách:

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
3

Hai danh sách này không giống nhau, nhưng mỗi mục trong chúng đều giống nhau:

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
4

Đây là một biểu diễn trực quan khá phức tạp của hai đối tượng này và những con trỏ mà chúng chứa:

Vì vậy, nếu chúng ta đột biến mục đầu tiên trong một danh sách, nó sẽ thay đổi cùng một mục trong danh sách khác:

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
5

Khi bạn sao chép một đối tượng trong Python, nếu đối tượng đó trỏ đến các đối tượng khác, bạn sẽ sao chép con trỏ vào các đối tượng khác thay vì tự sao chép các đối tượng.points to other objects, you'll copy pointers to those other objects instead of copying the objects themselves.

Các lập trình viên Python mới trả lời hành vi này bằng cách rắc

>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]
1 vào mã của họ. Hàm
>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]
2 cố gắng sao chép đệ quy một đối tượng cùng với tất cả các đối tượng mà nó trỏ đến.

Đôi khi các lập trình viên Python mới sẽ sử dụng

>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]
2 để sao chép các cấu trúc dữ liệu đệ quy:

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
6

Nhưng trong Python, chúng ta thường thích tạo các đối tượng mới thay vì biến đổi các đối tượng hiện có. Vì vậy, chúng tôi hoàn toàn có thể loại bỏ việc sử dụng

>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]
2 ở trên bằng cách lập một danh sách mới các từ điển mới thay vì sao chép sâu sắc danh sách từ điển cũ của chúng tôi.

>>> a, b, c, d, e, f, = [dict[] for x in range[6]]
7

Chúng ta có xu hướng thích các bản sao nông trong Python. Nếu bạn không đột biến các đối tượng không thuộc về bạn, bạn thường không có nhu cầu về

>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]
2.don't mutate objects that don't belong to you you usually won't have any need for
>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]
2.

Chức năng

>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]
2 chắc chắn có cách sử dụng của nó, nhưng nó thường không cần thiết. "Làm thế nào để tránh sử dụng
>>> numbers.pop[]
7
>>> numbers
[2, 1, 3, 4]
>>> numbers2
[2, 1, 3, 4]
2" đảm bảo một cuộc thảo luận riêng trong một bài viết trong tương lai.

Bản tóm tắt

Các biến trong Python không phải là thùng chứa mọi thứ; Chúng là con trỏ [chúng chỉ vào các đối tượng].pointers [they point to objects].

Mô hình biến và đối tượng của Python sôi sục đến hai quy tắc chính:

  1. Đột biến thay đổi một đối tượng changes an object
  2. Nhiệm vụ trỏ một biến vào một đối tượng points a variable to an object

Cũng như các quy tắc hệ quả này:

  1. Việc chỉ định lại một biến chỉ ra nó vào một đối tượng khác, để lại đối tượng gốc không thay đổi a variable points it to a different object, leaving the original object unchanged
  2. Bài tập không sao chép bất cứ điều gì, vì vậy bạn sẽ sao chép các đối tượng khi cần thiết anything, so it's up to you to copy objects as needed

Hơn nữa, các cấu trúc dữ liệu hoạt động theo cùng một cách: danh sách và từ điển con trỏ container cho các đối tượng thay vì chính các đối tượng. Và các thuộc tính hoạt động theo cùng một cách: các thuộc tính trỏ đến các đối tượng [giống như bất kỳ biến nào chỉ vào một đối tượng]. Vì vậy, các đối tượng không thể chứa các đối tượng trong Python [chúng chỉ có thể chỉ vào các đối tượng].pointers to objects rather than the objects themselves. And attributes work the same way: attributes point to objects [just like any variable points to an object]. So objects cannot contain objects in Python [they can only point to objects].

Và lưu ý rằng trong khi các đột biến thay đổi các đối tượng [không phải biến], nhiều biến có thể trỏ đến cùng một đối tượng. Nếu hai biến trỏ đến cùng một đối tượng thay đổi đối tượng đó sẽ được nhìn thấy khi truy cập một trong hai biến [vì cả hai đều trỏ đến cùng một đối tượng].mutations change objects [not variables], multiple variables can point to the same object. If two variables point to the same object changes to that object will be seen when accessing either variable [because they both point to the same object].

Để biết thêm về chủ đề này, xem:

  • Sê -ri screencast của tôi về các bài tập và đột biến trong Python
  • Ned Batchelder's Python Tên và Giá trị nói chuyện
  • Tên, đối tượng, đối tượng của Brandon Rhodes, và giảm mạnh từ cuộc nói chuyện vách đá

Mô hình tinh thần này của Python rất khó để nội tâm hóa nên không sao nếu nó vẫn cảm thấy khó hiểu! Các tính năng và thực tiễn tốt nhất của Python thường tự động hướng chúng tôi hướng tới việc "làm đúng". Nhưng nếu mã của bạn hoạt động một cách kỳ lạ, có thể là do thay đổi một đối tượng mà bạn không có ý thay đổi.

Bạn có thể gán một biến cho một biến trong Python không?

Việc gán một biến cho biến khác tạo ra một bí danh của mỗi biến. Một bí danh là biến chỉ vào cùng một đối tượng trong bộ nhớ như một biến khác. Trong ví dụ trên, cả hai biến var1 và var2 đều là bí danh của nhau. Trong Python, có thể phá hủy các tài liệu tham khảo.. An alias is variable that points to the same object in memory as another variable. In the example above, both variables var1 and var2 are aliases of each other. In Python, it is possible to destroy references.

Là các biến các biến Python?

Trong Python, các biến là các tham chiếu đến các đối tượng và bất kỳ biến nào cũng có thể tham chiếu bất kỳ đối tượng nào.Một biến được tạo bằng cách sử dụng nó.Đó là, các biến trong Python là động, không được biết và là các tham chiếu đến các đối tượng.variables are references to objects and any variable can reference any object. A variable is created by simply using it. That is, variables in Python are dynamic, untyped and are references to objects.

Điều nào sau đây không thể là một biến trong Python?

Một tên biến không thể bắt đầu với một số.Một tên biến chỉ có thể chứa các ký tự âm alpha và các tên biến [A-Z, 0-9 và _] là nhạy cảm trường hợp [tuổi, tuổi và tuổi là ba biến khác nhau]. A variable name can only contain alpha-numeric characters and underscores [A-z, 0-9, and _ ] Variable names are case-sensitive [age, Age and AGE are three different variables]

Có phải mọi biến python chỉ vào một đối tượng?

Từ một quan điểm, mọi thứ là một con trỏ trong Python.Ví dụ của bạn hoạt động rất giống mã C ++..every variable is a reference to an object.

Bài Viết Liên Quan

Chủ Đề