sách gpt4 ăn đã đi

Làm cách nào để tạo các biến có thể thay đổi? (Làm cách nào để tạo các biến có thể thay đổi?)

In lại Tác giả: trợ lý lỗi Thời gian cập nhật: 28-10-2023 20:45:15 28 4
mua khóa gpt4 giày nike



Tôi biết rằng một số ngôn ngữ khác, chẳng hạn như PHP, hỗ trợ khái niệm "tên biến" - nghĩa là nội dung của một chuỗi có thể được sử dụng như một phần của tên biến.

Tôi biết rằng một số ngôn ngữ khác, như PHP, hỗ trợ khái niệm "tên biến" - nghĩa là nội dung của chuỗi có thể được sử dụng như một phần của tên biến.


Tôi nghe nói đây là một ý tưởng tồi, nhưng tôi nghĩ nó sẽ giải quyết được một số vấn đề tôi gặp phải trong mã Python của mình.

Tôi nghe nói rằng nói chung đây không phải là một ý tưởng hay, nhưng tôi nghĩ nó có thể giải quyết một số vấn đề tôi đang gặp phải với mã Python của mình.


Có thể làm điều gì đó như thế này trong Python không? Có thể xảy ra lỗi gì?

Có thể làm điều gì đó như thế này bằng ngôn ngữ Python không? Điều gì có thể xảy ra?




Nếu bạn chỉ đang cố gắng tra cứu một cái hiện có biến theo tên của nó, xem Làm thế nào để tôi có thể chọn biến theo tên (chuỗi)?. Tuy nhiên, trước tiên hãy cân nhắc xem bạn có thể sắp xếp lại mã để tránh nhu cầu đó hay không bằng cách làm theo lời khuyên trong câu hỏi này.

Nếu bạn chỉ đang cố gắng tìm một biến hiện có theo tên, hãy xem Làm cách nào tôi có thể phân chia một biến theo tên (chuỗi)? Tuy nhiên, trước tiên hãy xem xét liệu mã có thể được sắp xếp lại như được đề xuất trong câu hỏi này hay không để tránh nhu cầu này.


Thêm câu trả lời

chính khía cạnh bảo trì và gỡ lỗi gây ra nỗi kinh hoàng. Hãy tưởng tượng việc cố gắng tìm ra biến 'foo' đã thay đổi ở đâu khi không có chỗ nào trong mã của bạn mà bạn thực sự thay đổi 'foo'. Hãy tưởng tượng thêm rằng đó là mã của người khác mà bạn phải bảo trì... OK, giờ bạn có thể đến nơi hạnh phúc của mình rồi.

Điều tạo ra nỗi sợ hãi này là khía cạnh bảo trì và gỡ lỗi. Hãy tưởng tượng bạn đang cố gắng tìm ra biến 'foo' đã thay đổi ở đâu khi không có chỗ nào trong mã của bạn mà 'foo' thực sự thay đổi. Hãy tưởng tượng lại rằng đó là mã của người khác mà bạn phải duy trì... Chà, bây giờ bạn có thể đến nơi hạnh phúc của mình.

Một cạm bẫy khác chưa được đề cập đến cho đến nay là nếu một biến được tạo động như vậy có cùng tên với một biến được sử dụng trong logic của bạn. Về cơ bản, bạn mở phần mềm của mình như một con tin cho đầu vào được cung cấp.

Một nhược điểm khác chưa được đề cập đến cho đến nay là nếu một biến được tạo động như vậy có cùng tên với biến được sử dụng trong logic của bạn. Về cơ bản, bạn mở phần mềm của mình làm con tin cho đầu vào mà nó cung cấp.

Bạn có thể sửa đổi các biến toàn cục và cục bộ của mình bằng cách truy cập các từ điển cơ bản cho chúng; đây là một ý tưởng tồi tệ theo quan điểm bảo trì ... nhưng có thể thực hiện được thông qua toàn cục().cập nhật()người dân địa phương().cập nhật() (hoặc bằng cách lưu tham chiếu dict từ bất kỳ từ điển nào trong số đó và sử dụng nó như bất kỳ từ điển nào khác). KHÔNG ĐƯỢC KHUYẾN NGHỊ ... nhưng bạn nên biết rằng điều đó là có thể.

Bạn có thể sửa đổi các biến toàn cục và cục bộ bằng cách truy cập các từ điển cơ bản của chúng; đây là một ý tưởng tồi từ góc độ bảo trì... nhưng nó hoạt động thông qua als().update() và cục bộ als().update() để hoàn thành (hoặc lưu tham chiếu từ điển vào cả hai từ điển và sử dụng nó như bất kỳ từ điển nào khác). Không được khuyến khích...nhưng bạn nên biết điều đó là có thể.

@JimDennis thực ra, không, nó không thể. Các sửa đổi đối với dict được trả về bởi người dân địa phương sẽ không ảnh hưởng đến không gian tên cục bộ trong CPython. Đây cũng là một lý do nữa để không làm điều đó.

@JimDennis Thật ra thì không thể. Các sửa đổi đối với lệnh được trả về cục bộ không ảnh hưởng đến không gian tên cục bộ trong CPython. Đây là một lý do khác để không làm điều đó.

@juanpa.arrivillaga: Tôi đã thử kiểm tra điều này trong một shell IPython, nhưng đã thực hiện ở cấp cao nhất (nơi locals() hoạt động giống như globsls()). Làm lại bài kiểm tra đó trong một mã lồng nhau (trong định nghĩa của một hàm) cho thấy rằng tôi không thể sửa đổi locals() từ bên trong đó. Như bạn nói, trợ giúp cho locals (3.7.6) có cảnh báo: "LƯU Ý: Việc cập nhật từ điển này có ảnh hưởng đến việc tra cứu tên trong phạm vi cục bộ hay ngược lại hay không là phụ thuộc vào việc thực hiện và không được bảo đảm về khả năng tương thích ngược."

@juanpa.arrivilaga: Tôi đã thử kiểm tra điều này trong IPython Shell, nhưng ở cấp cao nhất (biến cục bộ() hoạt động giống như lobsls()). Việc chạy lại bài kiểm tra trong mã lồng nhau (trong định nghĩa của hàm) thực sự cho thấy rằng tôi không thể sửa đổi các biến cục bộ () từ bên trong mã đó. Như bạn nói, trợ giúp bản địa hóa (3.7.6) có cảnh báo: "Lưu ý: Việc cập nhật từ điển này có ảnh hưởng đến việc tra cứu tên trong phạm vi cục bộ hay ngược lại hay không phụ thuộc vào việc triển khai và không chứa bất kỳ khả năng tương thích ngược nào Đảm bảo tình dục."

Khuyến nghị câu trả lời tuyệt vời

Bạn có thể sử dụng từ điển để thực hiện điều này. Từ điển là nơi lưu trữ khóa và giá trị.

Bạn có thể sử dụng từ điển để đạt được điều này. Từ điển là nơi lưu trữ các khóa và giá trị.


>>> dct = {'x': 1, 'y': 2, 'z': 3}
>>> dct
{'x': 1, 'y': 2, 'z': 3}
>>> dct["y"]
2

Bạn có thể sử dụng tên khóa biến để đạt được hiệu quả của các biến biến mà không có rủi ro bảo mật.

Bạn có thể sử dụng tên khóa biến để đạt được hiệu quả của biến mà không gặp rủi ro về bảo mật.


>>> x = "thư rác"
>>> z = {x: "trứng"}
>>> z["thư rác"]
'trứng'

Đối với những trường hợp bạn đang nghĩ đến việc làm điều gì đó như

Trong một số trường hợp bạn đang nghĩ đến việc làm điều gì đó như


var1 = 'foo'
var2 = 'thanh'
var3 = 'cơ sở'
...

Một danh sách có thể phù hợp hơn dict. Một danh sách biểu diễn một chuỗi các đối tượng được sắp xếp, với các chỉ số nguyên:

Một danh sách có thể phù hợp hơn một từ điển. Một danh sách đại diện cho một chuỗi các đối tượng được sắp xếp theo thứ tự, với chỉ mục số nguyên:


lst = ['foo', 'bar', 'baz']
print(lst[1]) # in thanh, vì chỉ số bắt đầu từ 0
lst.append('potatoes') # lst hiện là ['foo', 'bar', 'baz', 'potatoes']

Đối với các chuỗi được sắp xếp, danh sách thuận tiện hơn các dict có khóa là số nguyên, vì danh sách hỗ trợ lặp lại theo thứ tự chỉ mục, cắt lát, thêm vàovà các hoạt động khác đòi hỏi phải quản lý khóa phức tạp bằng dict.

Đối với các chuỗi có thứ tự, danh sách thuận tiện hơn từ điển có khóa số nguyên, vì danh sách hỗ trợ lặp, cắt, nối theo thứ tự chỉ mục và các hoạt động khác yêu cầu quản lý khóa vụng về khi sử dụng từ điển.



Sử dụng tích hợp sẵn lấy được chức năng để lấy thuộc tính trên một đối tượng theo tên. Sửa đổi tên nếu cần.

Nhận thuộc tính của đối tượng theo tên bằng hàm getattr tích hợp. Sửa đổi tên khi cần thiết.



obj.spam = 'trứng'
tên = 'thư rác'
getattr(obj, name) # trả về 'trứng'


Đây không phải là một ý tưởng hay. Nếu bạn đang truy cập một biến toàn cục, bạn có thể sử dụng toàn cục().

Đây không phải là một ý tưởng tốt. Nếu bạn muốn truy cập các biến toàn cục, bạn có thể sử dụng GLOBALS().



>>> a = 10
>>> toàn cục()['a']
10


Nếu bạn muốn truy cập một biến trong phạm vi cục bộ, bạn có thể sử dụng người dân địa phương(), nhưng bạn không thể gán giá trị cho dict trả về.

Nếu bạn muốn truy cập một biến trong phạm vi cục bộ, bạn có thể sử dụng biến cục bộ(), nhưng bạn không thể gán giá trị cho lệnh được trả về.



Một giải pháp tốt hơn là sử dụng lấy được hoặc lưu trữ các biến của bạn trong một từ điển và sau đó truy cập chúng theo tên.

Giải pháp tốt hơn là sử dụng getattr hoặc lưu trữ các biến trong từ điển và truy cập chúng theo tên.



Những người viết mã mới đôi khi viết mã như thế này:

Những lập trình viên mới đôi khi viết mã như thế này:



my_calculator.button_0 = tkinter.Button(gốc, văn bản=0)
my_calculator.button_1 = tkinter.Button(gốc, văn bản=1)
my_calculator.button_2 = tkinter.Button(gốc, văn bản=2)
...


Sau đó, người viết mã sẽ còn lại một đống các biến được đặt tên, với nỗ lực viết mã là O(tôi * N), Ở đâu tôi là số lượng các biến được đặt tên và N là số lần nhóm biến đó cần được truy cập (bao gồm cả việc tạo). Người mới bắt đầu tinh ý hơn sẽ nhận thấy rằng sự khác biệt duy nhất ở mỗi dòng đó là một con số thay đổi dựa trên một quy tắc và quyết định sử dụng vòng lặp. Tuy nhiên, họ bị mắc kẹt trong cách tạo động các tên biến đó và có thể thử một cái gì đó như thế này:

Sau đó, người lập trình sẽ nhận được một loạt các biến được đặt tên và khối lượng công việc mã hóa là O(m*n), trong đó m là số lượng biến được đặt tên và n là số lần nhóm biến cần được truy cập (bao gồm cả số lần được tạo). Những người mới bắt đầu tinh ý hơn nhận thấy rằng sự khác biệt duy nhất ở mỗi hàng là con số thay đổi theo quy tắc và quyết định sử dụng vòng lặp. Tuy nhiên, họ đang gặp khó khăn với cách tạo động các tên biến này và có thể thử những thứ như thế này:



đối với i trong phạm vi (10):
my_calculator.('button_%d' % i) = tkinter.Button(gốc, văn bản=i)


Họ nhanh chóng nhận ra rằng cách này không hiệu quả.

Họ nhanh chóng phát hiện ra điều này sẽ không hiệu quả.



Nếu chương trình yêu cầu "tên" biến tùy ý, từ điển là lựa chọn tốt nhất, như đã giải thích trong các câu trả lời khác. Tuy nhiên, nếu bạn chỉ muốn tạo nhiều biến và không ngại tham chiếu đến chúng bằng một chuỗi số nguyên, có lẽ bạn đang tìm kiếm danh sách. Điều này đặc biệt đúng nếu dữ liệu của bạn đồng nhất, chẳng hạn như dữ liệu nhiệt độ hàng ngày, điểm kiểm tra hàng tuần hoặc lưới các tiện ích đồ họa.

Nếu chương trình của bạn yêu cầu "tên" biến tùy ý, thì từ điển là lựa chọn tốt nhất, như được giải thích trong các câu trả lời khác. Tuy nhiên, nếu bạn chỉ đang cố gắng tạo nhiều biến và không ngại tham chiếu chúng bằng một chuỗi số nguyên thì có thể bạn đang tìm kiếm một danh sách. Điều này đặc biệt đúng nếu dữ liệu của bạn đồng nhất, chẳng hạn như chỉ số nhiệt độ hàng ngày, điểm bài kiểm tra hàng tuần hoặc một mạng lưới các tiện ích biểu đồ.



Có thể lắp ráp như sau:

Nó có thể được lắp ráp như sau:



nút_máy_tính_của_tôi = []
đối với i trong phạm vi (10):
my_calculator.buttons.append(tkinter.Button(root, text=i))


Cái này danh sách cũng có thể được tạo ra trong một dòng với sự hiểu biết:

Danh sách này cũng có thể được tạo trên một dòng với cách hiểu như sau:



my_calculator.buttons = [tkinter.Button(root, text=i) cho i trong phạm vi(10)]


Kết quả trong cả hai trường hợp đều là một dân số danh sách, với phần tử đầu tiên được truy cập bằng nút_máy_tính_của_tôi[0], tiếp theo với nút_máy_tính_của_tôi[1], v.v. Tên biến "cơ sở" trở thành tên của danh sách và sử dụng mã định danh khác nhau để truy cập vào nó.

Trong cả hai trường hợp, kết quả là một danh sách được điền sẵn, với phần tử đầu tiên được truy cập bằng my_culator.Button[0], phần tử tiếp theo được truy cập bằng my_culator.Button[1], v.v. Tên biến "cơ sở" trở thành tên của danh sách và mã định danh có thể thay đổi được sử dụng để truy cập vào danh sách đó.



Cuối cùng, đừng quên các cấu trúc dữ liệu khác, chẳng hạn như bộ - tương tự như một từ điển, ngoại trừ mỗi "tên" không có giá trị gắn liền với nó. Nếu bạn chỉ cần một "túi" các đối tượng, đây có thể là một lựa chọn tuyệt vời. Thay vì một cái gì đó như thế này:

Cuối cùng, đừng quên các cấu trúc dữ liệu khác, chẳng hạn như bộ - cấu trúc này tương tự như từ điển, ngoại trừ mỗi "tên" không có giá trị. Nếu bạn chỉ cần một túi đựng đồ thì đây có thể là một lựa chọn tốt. Thay vì một cái gì đó như thế này:



từ khóa_1 = 'táo'
từ khóa_2 = 'chuối'

nếu truy vấn == keyword_1 hoặc truy vấn == keyword_2:
in('Trùng khớp.')


Bạn sẽ có được điều này:

Bạn sẽ nhận được điều này:



từ khóa = {'táo', 'chuối'}
nếu truy vấn theo từ khóa:
in('Trùng khớp.')


Sử dụng một danh sách đối với một chuỗi các đối tượng tương tự, một bộ cho một túi đồ vật được sắp xếp tùy ý, hoặc một từ điển cho một túi tên có giá trị liên quan.

Sử dụng danh sách cho các chuỗi đối tượng tương tự, bộ cho các túi đối tượng được sắp xếp tùy ý và từ điển cho các túi tên có giá trị liên quan.



Bất cứ khi nào bạn muốn sử dụng các biến, có lẽ tốt hơn là sử dụng một từ điển. Vì vậy, thay vì viết

Khi bạn muốn sử dụng các biến có thể thay đổi, tốt hơn hết bạn nên sử dụng từ điển. Vì thế tôi đã không viết



$foo = "thanh"
$$foo = "baz"


bạn viết

bạn viết



mydict = {}
foo = "thanh"
mydict[foo] = "baz"


Bằng cách này, bạn sẽ không vô tình ghi đè lên các biến đã tồn tại trước đó (đây là khía cạnh bảo mật) và bạn có thể có nhiều "không gian tên" khác nhau.

Bằng cách này, bạn không vô tình ghi đè lên các biến hiện có trước đó (đây là vấn đề bảo mật) và bạn có thể có các "không gian tên" khác nhau.



Sử dụng toàn cục() (từ chối trách nhiệm: đây là một cách làm không tốt, nhưng lại là câu trả lời trực tiếp nhất cho câu hỏi của bạn, vui lòng sử dụng cấu trúc dữ liệu khác như trong câu trả lời được chấp nhận).

Sử dụng GLOBALS() (tuyên bố từ chối trách nhiệm: đây là một cách làm không tốt nhưng đó là câu trả lời trực tiếp nhất cho câu hỏi của bạn, hãy sử dụng các cấu trúc dữ liệu khác, như trong câu trả lời được chấp nhận).


Trên thực tế, bạn có thể gán các biến cho phạm vi toàn cục một cách động, ví dụ, nếu bạn muốn 10 biến có thể được truy cập trên phạm vi toàn cục tôi_1, tôi_2 ... tôi_10:

Trên thực tế, bạn có thể gán động các biến cho phạm vi toàn cục, ví dụ: nếu bạn muốn truy cập 10 biến trên phạm vi toàn cục I_1, I_2...I_10:


đối với i trong phạm vi (10):
globals()['i_{}'.format(i)] = 'a'

Điều này sẽ gán 'a' cho tất cả 10 biến này, tất nhiên bạn cũng có thể thay đổi giá trị một cách động. Tất cả các biến này có thể được truy cập ngay bây giờ giống như các biến được khai báo toàn cục khác:

Điều này sẽ gán 'a' cho tất cả 10 biến này, tất nhiên bạn cũng có thể thay đổi giá trị một cách linh hoạt. Bây giờ tất cả các biến này có thể được truy cập giống như các biến được khai báo toàn cục khác:


>>> tôi_5
'Một'


Thay vì một từ điển bạn cũng có thể sử dụng têntuple từ mô-đun bộ sưu tập, giúp truy cập dễ dàng hơn.

Bạn cũng có thể sử dụng các bộ dữ liệu được đặt tên từ mô-đun bộ sưu tập thay vì từ điển, điều này giúp việc truy cập dễ dàng hơn.


Ví dụ:

Ví dụ:


# sử dụng từ điển
biến = {}
biến["đầu tiên"] = 34
biến["thứ hai"] = 45
in(biến["đầu tiên"], biến["thứ hai"])

# sử dụng namedtuple
Biến = namedtuple('Biến', ['đầu tiên', 'thứ hai'])
v = Biến(34, 45)
in(v.first, v.second)


Các Không gian tên đơn giản lớp có thể được sử dụng để tạo ra các thuộc tính mới với thiết lập, hoặc lớp con Không gian tên đơn giản và tạo hàm của riêng bạn để thêm tên thuộc tính mới (biến).

Lớp SimpleNamespace có thể được sử dụng để tạo các thuộc tính mới với setattr hoặc lớp con SimpleNamespace và tạo các hàm của riêng bạn để thêm tên thuộc tính mới (các biến).



từ các loại nhập SimpleNamespace

biến = {"b":"B","c":"C"}
a = SimpleNamespace(**biến)
thiết lập(a,"g","G")
ag = "G+"
cái gì đó = aa


Nếu bạn không muốn sử dụng bất kỳ đối tượng nào, bạn vẫn có thể sử dụng thiết lập attr() bên trong mô-đun hiện tại của bạn:

Nếu bạn không muốn sử dụng bất kỳ đối tượng nào, bạn vẫn có thể sử dụng setattr() trong mô-đun hiện tại:



nhập khẩu hệ thống
current_module = module = sys.modules[__name__] # tức là "tệp" nơi mã của bạn được viết
setattr(current_module, 'variable_name', 15) # 15 là giá trị bạn gán cho var
print(variable_name) # >>> 15, được tạo từ một chuỗi


Biến đổi trong Python


"""
$a = 'xin chào';
$e = 'wow'
?>
$$a = 'thế giới';
?>
tiếng vang "$a ${$a}\n";
tiếng vang "$a ${$a[1]}\n";
?>
echo "$a $hello";
?>
"""

a = 'xin chào' #
e = 'wow' #
vars()[a] = 'thế giới' #
in(a, vars()[a]) #
in(a, vars()[vars()['a'][1]]) #
in(a, xin chào) #

Đầu ra:

Đầu ra:


Xin chào thế giới
xin chào wow
Xin chào thế giới



Sử dụng globals(), locals() hoặc vars() sẽ tạo ra kết quả tương tự


#
#
#
#
#
#

in('locals():\n')
a = 'xin chào'
e = 'wow'
người dân địa phương()[a] = 'thế giới'
in(a, người dân địa phương()[a])
in(a, người dân địa phương()[người dân địa phương()['a'][1]])
in(a, xin chào)

in('\n\ntoàn cục():\n')
a = 'xin chào'
e = 'wow'
globals()[a] = 'thế giới'
in(a, globals()[a])
in(a, globals()[globals()['a'][1]])
in(a, xin chào)

Đầu ra:

đầu ra:


người dân địa phương():

Xin chào thế giới
xin chào wow
Xin chào thế giới


toàn cục():

Xin chào thế giới
xin chào wow
Xin chào thế giới



Phần thưởng (tạo biến từ chuỗi)


# Python 2.7.16 (mặc định, 13 tháng 7 năm 2019, 16:01:51)
# [GCC 8.3.0] trên linux2

Tạo biến và giải nén tuple:


g = toàn cục()
danh sáchB = []
đối với i trong phạm vi (10):
g["số%s" % i] = i ** 10
listB.append("số{0}".format(i))

def printNum():
in "Đang in số 0 đến số 9:"
đối với i trong phạm vi (10):
in "num%s = " % i,
in g["num%s" % i]

printNum()

danh sáchA = []
đối với i trong phạm vi (10):
listA.append(i)

danh sáchA = bộ (danh sáchA)
in listA, '"Tuple để giải nén"'

listB = str(str(listB).strip("[]").replace("'", "") + " = listA")

in danh sáchB

danh sách thực thiB

printNum()

Đầu ra:

Đầu ra:


In số 0 đến số 9:
số0 = 0
số1 = 1
số2 = 1024
số 3 = 59049
số4 = 1048576
số5 = 9765625
số6 = 60466176
số 7 = 282475249
số8 = 1073741824
số 9 = 3486784401
(0, 1, 2, 3, 4, 5, 6, 7, 8, 9) "Bộ để giải nén"
số0, số1, số2, số3, số4, số5, số6, số7, số8, số9 = danh sáchA
In số 0 đến số 9:
số0 = 0
số1 = 1
số2 = 2
số3 = 3
số4 = 4
số5 = 5
số 6 = 6
số 7 = 7
số8 = 8
số 9 = 9


Bạn phải sử dụng toàn cục() phương pháp xây dựng để đạt được hành vi đó:

Bạn phải sử dụng phương thức tích hợp GLOBALS() để đạt được hành vi này:


def var_of_var(k, v):
toàn cục()[k] = v

in tên_biến # NameError: tên 'tên_biến' không được xác định
some_name = 'tên_biến'
globals()[tên_số_số] = 123
in(tên_biến) # 123

some_name = 'biến_tên2'
var_of_var(some_name, 456)
in(tên_biến2) # 456


Tôi đang trả lời câu hỏi Làm thế nào để lấy giá trị của một biến theo tên của nó trong một chuỗi?
đã được đóng lại như một bản sao với một liên kết đến câu hỏi này. (Ghi chú của biên tập viên: Bây giờ nó đã được đóng lại như một bản sao của Làm thế nào để tôi có thể chọn biến theo tên (chuỗi)?)

Câu hỏi tôi muốn trả lời là, làm cách nào để lấy giá trị của một biến có tên đã cho trong một chuỗi? Nó được đóng dưới dạng bản sao có liên kết đến câu hỏi này. (Ghi chú của biên tập viên: Hiện tại nó đã bị đóng dưới dạng bản sao của Cách chọn biến theo tên (chuỗi)?)




Nếu các biến đang đề cập là một phần của đối tượng (ví dụ như một phần của lớp) thì một số hàm hữu ích để đạt được chính xác điều đó là hasattr, lấy được, Và thiết lập.

Nếu biến được đề cập là một phần của một đối tượng (ví dụ: một phần của một lớp), thì có một số hàm hữu ích để đạt được điều này: hasattr, getattr và setattr.


Vì vậy, ví dụ bạn có thể có:

Ví dụ: bạn có thể có:


Biến lớp (đối tượng):
định nghĩa __init__(bản thân):
self.foo = "biến_ban_đầu"

def create_new_var(self, tên, giá trị):
setattr(self, tên, giá trị)

def get_var(bản thân, tên):
nếu hasattr(self, name):
trả về getattr(self, name)
khác:
raise "Lớp không có biến có tên là: " + name

Sau đó bạn có thể làm:

Sau đó, bạn có thể làm như sau:


>>> v = Biến()
>>> v.get_var("foo")
'biến_ban_đầu'

>>> v.create_new_var(v.foo, "thực ra không phải là khởi tạo")
>>> v.biến_ban_đầu
'thực ra không phải là ban đầu'


Tôi đã thử cả hai trong python 3.7.3, bạn có thể sử dụng globals() hoặc vars()

Tôi đã thử cả hai trong Python3.7.3, bạn có thể sử dụng Global() hoặc vars()



>>> thực phẩm #Lỗi
>>> sữa lắc #Lỗi
>>> thực phẩm="bánh mì"
>>> uống="sữa lắc"
>>> globals()[food] = "hương dâu tây"
>>> vars()[drink] = "hương vị sô cô la"
>>> bánh mì
'hương vị dâu tây'
>>> sữa lắc
'hương vị sô cô la'
>>> toàn cục()[uống]
'hương vị sô cô la'
>>> vars()[thức ăn]
'hương vị dâu tây'





Thẩm quyền giải quyết:

https://www.daniweb.com/programming/software-development/threads/111526/setting-a-string-as-a-variable-name#post548936

Tham khảo: https://www.daniweb.com/programming/software-development/threads/111526/setting-a-string-as-a-variable-name#post548936



Sự đồng thuận là sử dụng từ điển cho việc này - xem các câu trả lời khác. Đây là một ý tưởng hay cho hầu hết các trường hợp, tuy nhiên, có nhiều khía cạnh phát sinh từ điều này:

Sự đồng thuận là sử dụng từ điển để giải thích điều này - xem các câu trả lời khác. Trong hầu hết các tình huống, đây là một ý tưởng hay, tuy nhiên, có nhiều khía cạnh phát sinh từ nó:




  • Bạn sẽ tự chịu trách nhiệm cho từ điển này, bao gồm cả việc thu gom rác (của các biến in-dict) v.v.

  • không có tính cục bộ hoặc tính toàn cục cho các biến biến, nó phụ thuộc vào tính toàn cục của từ điển

  • nếu bạn muốn đổi tên một biến, bạn sẽ phải thực hiện thủ công

  • tuy nhiên, bạn linh hoạt hơn nhiều, ví dụ


    • bạn có thể quyết định ghi đè lên các biến hiện có hoặc ...

    • ... chọn triển khai các biến hằng số

    • để đưa ra ngoại lệ về việc ghi đè cho các loại khác nhau

    • vân vân.




Nói như vậy, tôi đã thực hiện một quản lý biến đổi biến-class cung cấp một số ý tưởng trên. Nó hoạt động với python 2 và 3.

Điều đó có nghĩa là tôi đã triển khai một lớp trình quản lý biến có thể cung cấp một số ý tưởng ở trên. Nó hoạt động trên Python 2 và 3.



Bạn sẽ sử dụng lớp học như thế này:

Bạn có thể sử dụng lớp này như thế này:



từ biếnVariablesManager nhập VariableVariablesManager

myVars = Biến đổiBiếnQuản lý()
myVars['test'] = 25
in(myVars['test'])

# định nghĩa một biến hằng số
myVars.defineConstVariable('myconst', 13)
thử:
myVars['myconst'] = 14 # <- điều này gây ra lỗi, vì 'myconst' không được thay đổi
print("không được phép")
ngoại trừ AttributeError như e:
vượt qua

# đổi tên một biến
myVars.renameVariable('myconst', 'myconstOther')

# bảo tồn địa phương
định nghĩa testLocalVar():
myVars = Biến đổiBiếnQuản lý()
myVars['test'] = 13
print("bên trong hàm myVars['test']:", myVars['test'])
kiểm tra Biến cục bộ()
print("bên ngoài hàm myVars['test']:", myVars['test'])

# định nghĩa một biến toàn cục
myVars.defineGlobalVariable('globalVar', 12)
kiểm tra defGlobalVar():
myVars = Biến đổiBiếnQuản lý()
print("bên trong hàm myVars['globalVar']:", myVars['globalVar'])
myVars['globalVar'] = 13
print("bên trong hàm myVars['globalVar'] (đã được thay đổi):", myVars['globalVar'])
testGlobalVar()
print("bên ngoài hàm myVars['globalVar']:", myVars['globalVar'])


Nếu bạn chỉ muốn cho phép ghi đè các biến có cùng kiểu:

Nếu bạn chỉ muốn cho phép ghi đè các biến cùng loại:



myVars = VariableVariablesManager(enforceSameTypeOnOverride = Đúng)
myVars['test'] = 25
myVars['test'] = "Cat" # <- gây ra Ngoại lệ (kiểu khác khi ghi đè)


Bất kỳ tập hợp biến nào cũng có thể được gói gọn trong một lớp.
Biến "có thể" được thêm vào phiên bản lớp trong thời gian chạy bằng cách truy cập trực tiếp vào từ điển tích hợp thông qua thuộc tính __dict__.

Bất kỳ tập hợp biến nào cũng có thể được gói trong một lớp. Các biến có thể được thêm vào các thể hiện của lớp trong thời gian chạy bằng cách truy cập trực tiếp vào từ điển tích hợp thông qua thuộc tính __dict__.



Mã sau đây định nghĩa lớp Variables, lớp này thêm các biến (trong trường hợp này là các thuộc tính) vào thể hiện của nó trong quá trình xây dựng. Tên biến được lấy từ một danh sách được chỉ định (ví dụ, có thể được tạo ra bởi mã chương trình):

Mã bên dưới định nghĩa lớp Biến, lớp này thêm các biến (thuộc tính trong trường hợp này) vào các thể hiện của nó trong quá trình xây dựng. Tên biến được lấy từ một danh sách cụ thể (ví dụ: nó có thể được tạo bởi mã chương trình):



# một số danh sách tên biến
L = ['a', 'b', 'c']

Biến lớp:
định nghĩa __init__(bản thân, L):
cho mục trong L:
self.__dict__[mục] = 100

v = Biến(L)
in(va, vb, vc)
#sẽ sản xuất 100 100 100


Việc này có thể cực kỳ rủi ro...
nhưng bạn có thể sử dụng exec():

Điều này hẳn sẽ rất nguy hiểm... Nhưng bạn có thể sử dụng exec():


a = 'b=5'
thực hiện(a)
c = b*2
in (c)

Kết quả:
10

Kết quả: 10 người



Các thiết lập attr() phương thức này thiết lập giá trị của thuộc tính được chỉ định của đối tượng được chỉ định.

Chức năng của phương thức là đặt giá trị của thuộc tính được chỉ định của đối tượng được chỉ định.


Cú pháp như thế này –

Nó diễn ra như thế này -


setattr(đối tượng, tên, giá trị)
Ví dụ -

setattr(bản thân, id, 123)

tương đương với self.id = 123

Tương đương với self.id=123


Như bạn có thể đã quan sát, setattr() mong đợi một đối tượng được truyền cùng với giá trị để tạo/sửa đổi một thuộc tính mới.

Như bạn có thể nhận thấy, setattr() dự kiến ​​sẽ được chuyển một đối tượng và giá trị để tạo/sửa đổi các thuộc tính mới.


Chúng ta có thể sử dụng setattr() với giải pháp thay thế để có thể sử dụng trong các mô-đun. Đây là cách thực hiện –

Chúng ta có thể sử dụng setattr() với một cách giải quyết khác để có thể sử dụng nó trong một mô-đun. Đây là "Làm thế nào để--"


nhập khẩu hệ thống
x = "Pikachu"
giá trị = 46
mô-đun này = sys.modules[__name__]
setattr(thismodule, x, giá trị)
in(pikachu)


TL;DR: Hãy cân nhắc sử dụng đánh giá()

TL;DR: Cân nhắc sử dụng eval()


Tôi tìm thấy trang này vì tôi đang tìm cách thực hiện một số xử lý mẫu đơn giản với các hàm chuỗi Python (trừ khi bao gồm một công cụ mẫu đầy đủ). Tôi đang tìm cách thiết lập các biến cục bộ và đó là cách tôi đến đây.

Tôi tìm thấy trang này vì tôi muốn thực hiện một số xử lý mẫu đơn giản bằng cách sử dụng các hàm chuỗi python (không bao gồm công cụ tạo mẫu đầy đủ). Tôi đang tìm cách đặt các biến cục bộ và đó là điều đã đưa tôi đến đây.


Vấn đề của tôi bắt đầu với một mẫu đơn giản:

Vấn đề của tôi bắt đầu với một mẫu đơn giản:


Xin chào, {tên}

Cách tôi điền mẫu này là như thế này:

Cách tôi điền mẫu này là thế này:


def populate(mẫu,biến):
trả về template.format(**biến)

Và thế là điều này sẽ có hiệu quả:

Vì vậy, điều này hoạt động:


giá trị = {
'tên': 'Stack Overflow'
}
my_template = "Xin chào, {name}"
in( điền(my_template, giá trị))

# đầu ra
Xin chào, Stack Overflow

Nhưng rồi mọi thứ nhanh chóng trở nên tồi tệ. Tôi đã thử một mẫu mới mà tôi chỉ muốn từ đầu tiên:

Nhưng mọi thứ nhanh chóng đi về phía nam. Tôi đã thử một mẫu mới và tôi chỉ muốn từ đầu tiên:


Bây giờ mẫu của tôi là thế này: "Xin chào, {name.split()[0]}" và đoạn mã này bị lỗi.

Bây giờ mẫu của tôi là: "Xin chào, {name.plit()[0]}" và có gì đó không ổn với mã này.


giá trị['tên'] = "Stack Overflow"
my_template = "Xin chào, {name.split()[0]}"
in(điền(my_template, giá trị)
# đầu ra (tốt, stderr)
AttributeError: đối tượng 'str' không có thuộc tính 'split()'. Ý bạn là: 'split'?

Và sau đó tôi biết rằng hàm định dạng không hoạt động theo cách tôi muốn. Bạn không thể truyền mã tùy ý vào nó. Bạn cần truyền cho nó các thứ định dạng. Và vì vậy tôi đã thử một giải pháp khác. Tôi đã mã hóa cư trú sử dụng đánh giá và một chuỗi f thay vì định dạng. Một f-string (không giống như định dạng) cho phép mã python trong nội suy dấu ngoặc nhọn. Vì vậy, một f-string như thế này `f"Hello, {name.split()[0]}" có hiệu quả. Chúng ta hãy xem mã cho phần nhỏ này (để bạn không phải rời khỏi bài đăng này để tìm hiểu f-string):

Sau đó tôi được biết rằng chức năng định dạng không hoạt động như tôi mong muốn. Bạn không thể truyền mã tùy ý cho nó. Bạn cần chuyển nội dung được định dạng cho nó. Vì vậy, tôi đã thử một giải pháp khác. Tôi đã mã hóa Popate để sử dụng chuỗi val và f thay vì định dạng. Chuỗi F (không giống như các định dạng) cho phép sử dụng mã Python trong phép nội suy dấu ngoặc nhọn. Vì vậy, một chuỗi f như `f "Xin chào, {name.plit()[0]}" không hoạt động. Chúng ta hãy xem đoạn mã nhỏ này (để bạn không cần phải rời khỏi bài đăng này để tìm hiểu về chuỗi f):


tên = "Stack Overflow"
in(f"Xin chào, {name.split()[0]}")
# Đầu ra:
Xin chào, Stack

Bây giờ tôi chỉ cần sử dụng một chuỗi f. Vì vậy, tôi đã sử dụng đánh giá. Dân số mới của tôi là:

Bây giờ tôi chỉ cần sử dụng chuỗi F. Vì vậy, tôi đã sử dụng eval. Thành viên mới của tôi là:


def populate(mẫu,biến):
trả về eval(f'f"{template}"')

Nhưng khi tôi chạy lại chương trình, tôi nhận được lỗi này:

Nhưng khi tôi chạy lại chương trình, tôi gặp lỗi này:


NameError: tên 'name' không được xác định

Tôi nên chỉ ra rằng một f-string có thể điền vào chuỗi với bất kỳ biến toàn cục hoặc cục bộ nào trong phạm vi. Để khắc phục sự cố của mình, tôi có thể thay đổi mẫu của mình thành "Xin chào, {biến['tên']}" từ biến số chắc chắn nằm trong phạm vi. Đây thực sự là cách tiếp cận tệ vì bây giờ người viết mẫu phải biết về biến số từ điển. Thay vào đó, tôi muốn làm cho mọi khóa có sẵn trong biến số từ điển có sẵn cho tác giả mẫu, như tôi đã có trước đây với định dạng(**biến).

Tôi nên chỉ ra rằng chuỗi f có khả năng điền các chuỗi có bất kỳ biến toàn cục hoặc cục bộ nào trong phạm vi. Để giải quyết vấn đề của mình, tôi có thể thay đổi mẫu của mình thành "Xin chào, {Variables['name']}" vì các biến chắc chắn nằm trong phạm vi. Đây là một cách tiếp cận rất tệ vì bây giờ người viết mẫu phải biết về từ điển biến. Thay vào đó, tôi muốn cung cấp mọi khóa trong từ điển biến cho tác giả mẫu, giống như tôi đã làm trước đây với Format(**Variables).


Để giải quyết vấn đề của mình, tôi muốn thiết lập các biến cục bộ dựa trên nội dung của biến số từ điển được chuyển đến điền vào() chức năng.

Để giải quyết vấn đề của mình, tôi muốn đặt các biến cục bộ dựa trên nội dung của từ điển biến được truyền cho hàm Popate().


Tôi đã thử cách này:

Tôi đã thử điều này:


locals() = biến

Và điều đó không hiệu quả:

Nhưng điều này không hiệu quả:


    locals() = biến
^^^^^^^^
SyntaxError: không thể gán cho lệnh gọi hàm ở đây. Có thể bạn muốn nói '==' thay vì '='?

Và sau đó tôi đã thử cách này và nó hiệu quả:

Sau đó tôi đã thử và nó đã hoạt động:


def populate(mẫu,biến):
đối với k,v trong variables.items():
người dân địa phương()[k] = v
trả về eval(f'f"{template}"')


giá trị = {
'tên': 'Stack Overflow'
}
my_template = "Xin chào, {name.split()[0]}"
in( điền(my_template, giá trị))

Và vì vậy, điều đầu tiên cần rút ra là bạn có thể tạo các biến cục bộ trong một chức năng (hoặc toàn cục) bằng cách đặt cặp giá trị khóa trong từ điển locals().

Vì vậy, lợi ích đầu tiên là bạn có thể tạo các biến cục bộ trong một hàm (hoặc biến toàn cục) bằng cách đặt các cặp khóa-giá trị trong từ điển LOCALS().


Trong trường hợp của đánh giá, tham số thứ hai và thứ ba cho phép bạn truyền vào các biến cục bộ và toàn cục, do đó bạn có thể đơn giản hóa hàm populate thành như sau:

Trong trường hợp val, tham số thứ hai và thứ ba cho phép bạn chuyển các biến cục bộ và biến toàn cục, do đó bạn có thể đơn giản hóa hàm điền thành:


def populate(mẫu,biến):
trả về eval(f'f"{template}"',biến)

Trên đây là cách tôi sử dụng đánh giá để thực hiện dân số chuỗi f (hoặc đánh giá mẫu đơn giản). Nhưng đánh giá cũng có thể được sử dụng để cung cấp các biến thay đổi.

Trên đây là cách tôi sử dụng eval cho phần đệm chuỗi f (hoặc các phép tính mẫu đơn giản). Nhưng val cũng có thể được sử dụng để cung cấp các biến.


Thêm câu trả lời

locals().update({'new_local_var':'một số giá trị cục bộ'}) hoạt động tốt với tôi trong Python 3.7.6; vì vậy tôi không chắc bạn có ý gì khi nói rằng bạn không thể gán giá trị thông qua nó.

Locals().update('new_local_var':'some local value'}) chỉ hoạt động tốt với tôi trong Python 3.7.6; vì vậy tôi không hiểu ý bạn khi nói rằng bạn không thể gán giá trị thông qua nó.

Được cho x = "foo"người dân địa phương()["x"] = "thanh" sử dụng in x cung cấp đầu ra thanh cho Jython 2.5.2. Điều này đã được thử nghiệm với một tập lệnh tự động hóa theo yêu cầu trong tối đa.

Sử dụng print x bạn có thể nhận được thanh đầu ra của Jython2.5.2, cho x = "foo" và local()["x"] = "bar". Điều này đã được thử nghiệm với tập lệnh tự động hóa theo yêu cầu trong Maximo.

Tài liệu của người dân địa phương() nói cụ thể: "Nội dung của từ điển này phải không được sửa đổi." (tôi nhấn mạnh)

Tài liệu về Locals() nêu rõ: "Không nên sửa đổi nội dung của từ điển này." (nhấn mạnh của tôi)

@JimDennis`locals()`` cung cấp một từ điển được tạo ra để đại diện biến cục bộ. Việc cập nhật nó không đảm bảo cập nhật thật sự biến cục bộ. Trong các triển khai Python hiện đại, nó giống như một bức tranh (hiển thị nội dung) trong một khung đẹp (cấp cao từ điển) – việc vẽ lên bức tranh thực tế sẽ không làm thay đổi được bức tranh thực tế.

@JimDennis `Locals()`` cung cấp các từ điển được tạo để thể hiện các biến cục bộ. Việc cập nhật nó không đảm bảo việc cập nhật biến cục bộ thực tế. Trong các triển khai Python hiện đại, nó giống như một bức tranh (hiển thị nội dung) trong một khung đẹp (từ điển cấp cao) - việc vẽ lên bức tranh không thực sự thay đổi thực tế.

Lý do nó không hoạt động, ít nhất là trên CPython, là vì CPython phân bổ một mảng có kích thước cố định cho các hàm cục bộ và kích thước của mảng đó được xác định khi hàm được định nghĩa, không phải khi hàm chạy và không thể thay đổi (quyền truy cập vào các hàm cục bộ thực sự thậm chí không sử dụng tên; tên được thay thế bằng chỉ mục trong mảng tại thời điểm biên dịch hàm). người dân địa phương() trả về một giá trị đúng từ điển; trong một hàm, rằng từ điển được thực hiện bằng cách tải tên và các giá trị liên quan trong mảng khi bạn gọi người dân địa phương(), nó sẽ không thấy những thay đổi trong tương lai. Nếu nó thay đổi, bạn đang ở phạm vi toàn cục hoặc phạm vi lớp (sử dụng từ điển phạm vi).

Lý do nó không hoạt động là vì, ít nhất là trên CPython, CPython phân bổ một mảng có kích thước cố định cho các biến cục bộ và kích thước của mảng được xác định khi hàm được xác định, không phải khi hàm được chạy và không thể đã thay đổi (Quyền truy cập vào biến cục bộ thực thậm chí không sử dụng tên; tên được thay thế bằng chỉ mục trong mảng khi hàm được biên dịch). Locals() trả về một lệnh thực; trong hàm, khi bạn gọi Locals(), lệnh này được tạo bằng cách tải tên và các giá trị liên quan trong một mảng và nó không thấy các thay đổi trong tương lai. Nếu nó thay đổi thì nó ở phạm vi toàn cục hoặc phạm vi lớp (sử dụng phạm vi DICT).

Hãy ghi nhớ têntuples không thể thay đổi nên chúng hơi khác so với dict chỉ có ký hiệu dấu chấm. Tuy nhiên, cả hai tùy chọn đều thúc đẩy các nguyên tắc thiết kế tốt và không lạm dụng không gian tên toàn cục như một nửa các câu trả lời trong chuỗi này.

Hãy nhớ rằng các bộ dữ liệu được đặt tên là bất biến, vì vậy chúng hơi khác so với việc đọc chính tả đơn giản bằng ký hiệu dấu chấm. Phải nói rằng, cả hai tùy chọn đều thúc đẩy các nguyên tắc thiết kế tốt và không lạm dụng không gian tên chung giống như một nửa số câu trả lời trong bài viết này.

Điều này không hiệu quả với __chỉ thị__ Tuy nhiên, biến đổi. Tôi tự hỏi liệu có một cơ chế chung để tạo ra bất kì biến toàn cục một cách năng động.

Tuy nhiên, điều này không hoạt động với các biến __dict__. Tôi tự hỏi liệu có cơ chế chung nào để tự động tạo bất kỳ biến toàn cục nào không.

toàn cục() có thể làm điều này

GLOBAL() có thể làm điều này

Các của aingười dân địa phương dicts không thể được sửa đổi bên trong một hàm. Và trạng thái toàn cầu có thể thay đổi là xấu ngoại trừ có thể trong các tập lệnh đơn giản nhất. Vì vậy, điều này chỉ có ích hạn chế.

Các biến và biến cục bộ DICT không thể được sửa đổi bên trong một hàm. Và trạng thái toàn cầu có thể thay đổi là xấu ngoại trừ trong các tập lệnh đơn giản nhất. Vì vậy, điều này được sử dụng hạn chế.

Điều này sẽ tạo ra một chuỗi, điều này là không được phép. TypeError: ngoại lệ phải bắt nguồn từ BaseException. Nhưng tại sao lại bận tâm đến hasattr()nâng lên khi bạn chỉ có thể làm lấy attr() vô điều kiện và để nó tăng lên Thuộc tínhError dành cho bạn?

Điều này ném một chuỗi, không được phép. TypeError: Ngoại lệ phải bắt nguồn từ BaseException. Nhưng tại sao phải bận tâm với hasattr() và Raise khi bạn có thể thực hiện getattr() vô điều kiện và yêu cầu nó tăng AttributionError cho bạn?

Điều này sẽ không hoạt động bên trong một hàm. Về cơ bản nó tương đương với hàm an toàn hơn người dân địa phương()['b'] = 5 (điều này cũng không có tác dụng trong một hàm).

Điều này không hoạt động bên trong một chức năng. Về cơ bản, nó tương đương với LOCALS()['b']=5 an toàn hơn (cũng không hoạt động bên trong một hàm).

@benrg Bạn có biết cách giải quyết đề xuất không thành công của Rubens không vì tôi cũng đang gặp tình huống tương tự? Tôi có một tệp chứa danh sách dài các phép gán biến dưới dạng chuỗi tập thể. Tôi cần chuyển chúng thành phép gán python nhưng cả eval() và exec() đều không thành công.

@benrg Bạn có biết cách giải quyết lời khuyên thất bại của Rubens không, vì tôi cũng đang mắc kẹt trong tình huống tương tự? Tôi có một tệp chứa danh sách dài các phép gán biến dưới dạng chuỗi tập hợp. Tôi cần chuyển đổi chúng thành các bài tập Python, nhưng cả val() và exec() đều thất bại.

Nó dễ sử dụng hơn toàn cục().

Sử dụng GLOBAL() dễ dàng hơn.

28 4 0
trợ lý lỗi
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress