Có xóa xóa khỏi bộ nhớ python không?

Vì vậy, tôi đã bắt đầu hỗ trợ một công cụ… thiết kế của nó rất thú vị và nó hoạt động, nhưng nó chắc chắn không phải là lý tưởng

Trong thời gian chạy, khi một yêu cầu đến, nó sẽ lấy một kho lưu trữ các tệp nguồn Python từ một kho lưu trữ và sử dụng

type[a] == type[d] == type[g]
0 để 'chạy' chúng trong trình thông dịch hiện tại. Các tệp này xác định một số lớp, sau đó được đăng ký thông qua lớp cha vào danh sách và công cụ sử dụng các lớp đó để xử lý yêu cầu

Khi yêu cầu tiếp theo đến, nó làm trống danh sách [xóa mọi tham chiếu đến các lớp đó] và thực hiện lại toàn bộ. Thông thường, điều này hoạt động tốt, trừ khi nội dung của các tệp nguồn đó đã thay đổi theo một số cách nhất định, như tôi đã làm hôm nay. Cụ thể, nếu một trong các lớp được đổi tên hoặc một trong các lớp bị xóa, nó sẽ vẫn nằm trong bộ nhớ trong trình thông dịch và khi lớp cha quay vòng qua tất cả các lớp con, nó sẽ được đăng ký lại. Do đó, đối với một số loại thay đổi nội dung trong tệp nguồn, quy trình phải được 'trả lại' để xóa các lớp cũ khỏi bộ nhớ của trình thông dịch

Bây giờ… các lớp là các đối tượng và tôi có thể gọi

type[a] == type[d] == type[g]
1 trên bất kỳ đối tượng nào tôi muốn để đánh dấu nó để xóa và tôi có các tham chiếu đến các đối tượng lớp này. Tôi khá chắc chắn rằng nếu tôi làm vậy thì trên thực tế các đối tượng sẽ không bị xóa, bởi vì có các tham chiếu khác đến chúng ở những nơi khác trong trình thông dịch

Có cách nào không xấu để loại bỏ các đối tượng lớp này khỏi trình thông dịch mà không cần khởi động lại nó không?

Vì vậy, tôi đã bắt đầu hỗ trợ một công cụ… thiết kế của nó rất thú vị,

Đó là một… thú vị… cách sử dụng từ “thú vị”

Bạn có ý nghĩa gì bởi "hỗ trợ"?

Nếu bạn mới sử dụng nó, bạn nên hỏi người bảo trì để họ tư vấn

Ngoài ra, bạn nên cho chúng tôi biết công cụ này được gọi là gì, không chỉ mô tả nó

nó lấy một kho lưu trữ các tệp nguồn Python từ một kho lưu trữ và sử dụng

type[a] == type[d] == type[g]
0 để 'chạy' chúng trong trình thông dịch hiện tại

Thật là một thiết kế kỳ lạ. Tôi tự hỏi liệu có lý do nào cho nó hay nó chỉ phát triển từ mã được viết bởi ai đó không hiểu việc nhập mô-đun

Khi yêu cầu tiếp theo đến, nó sẽ làm trống danh sách [xóa mọi tham chiếu đến các lớp đó],

Chà, không, chỉ xóa danh sách không xóa các tham chiếu đến các lớp. Thiết kế này có vẻ như có ít nhất bốn tham chiếu đến từng đối tượng lớp

  1. đối tượng lớp được tạo bởi
    type[a] == type[d] == type[g]
    
    0ing nguồn, mà tôi sẽ gọi là “C”;
  2. tham chiếu đến C trong danh sách;
  3. tham chiếu đến C được giữ bởi mọi phiên bản của C
  4. nếu có bất kỳ lớp con nào của C, thì mỗi lớp con đó cũng giữ các tham chiếu trở lại C

Có thể có những người khác

Tôi sẽ cho rằng cái đầu tiên được tạo trong một số loại đối tượng không gian tên tạm thời hoặc cục bộ, sẵn sàng để thu gom rác

# Inside some function, ns is a local and registry is a global.
# When the function exits, ns is deleted.
ns = {}
exec[source, ns, ns]
registry.append[ns['C']]  # Save the class object.

Nhưng việc xóa các mục trong danh sách, số 2 ở trên, không ảnh hưởng gì đến các tham chiếu do các phiên bản nắm giữ. Nếu bất kỳ trường hợp nào trong số đó vẫn còn tồn tại, bạn sẽ xây dựng các lớp vô hình gần như không thể truy cập được, gây lãng phí bộ nhớ

  • yêu cầu 1 tạo các thể hiện a, b, c tham chiếu đến lớp C;
  • yêu cầu 2 tạo các thể hiện d, e, f tham chiếu đến lớp C;
  • yêu cầu 3 tạo các thể hiện g, h, i đề cập đến lớp C

Mặc dù mã nguồn của C giống nhau và tên giống nhau, nhưng mỗi yêu cầu tạo ra một đối tượng lớp riêng biệt. Nếu thậm chí một trường hợp duy nhất tồn tại theo yêu cầu mà không bị thu gom rác, thì các lớp cũng sẽ tồn tại

Giả sử a, d, g sống sót sau yêu cầu, sau đó

type[a] == type[d] == type[g]

sẽ trả về Sai

Và đó là lý do tại sao các thay đổi đối với mã nguồn không được lan truyền ngược sang các phiên bản được tạo trong các yêu cầu trước đó. Nếu bạn thực hiện thay đổi đối với mã nguồn của C sau yêu cầu 2 nhưng trước yêu cầu 3 thì chỉ có

type[a] == type[d] == type[g]
1 thấy thay đổi đó,
type[a] == type[d] == type[g]
2 và
type[a] == type[d] == type[g]
3 sẽ vẫn tham chiếu đến phiên bản trước khi thay đổi

Sửa đổi trực tiếp mã nguồn Python là… không dễ dàng. Đẩy những sửa đổi đó trở lại các phiên bản đã tồn tại là một việc khó. Tôi không hoàn toàn chắc chắn rằng chỉ cần thay đổi

type[a] == type[d] == type[g]
4 là đủ, mặc dù có thể

Vì vậy, về nguyên tắc, điều này sẽ dễ dàng, nhưng trong thực tế, việc có được quyền ghi sổ có thể bị cấm, dẫn đến những bất ngờ. Đây là lý do tại sao hàm

type[a] == type[d] == type[g]
5 bị chuyển từ nội trang sang mô-đun funcools trong Python 3. 0

Có cách nào không xấu để loại bỏ các đối tượng lớp này khỏi trình thông dịch mà không cần khởi động lại nó không?

Không ác?

Không có cách nào để loại bỏ một lớp cho đến khi tất cả các tham chiếu đến nó không còn nữa [nếu không thì trình thông dịch có thể phân tách lỗi]. Vì vậy, bạn phải loại bỏ bất kỳ và mọi tham chiếu đến lớp

Bạn có thể thử sử dụng mô-đun

type[a] == type[d] == type[g]
6 để tìm kiếm các đối tượng tham chiếu đến đối tượng lớp đó

Steven D'Aprano

Bạn có ý nghĩa gì bởi "hỗ trợ"?

Bây giờ tôi là người bảo trì chính của nó, mặc dù tác giả ban đầu vẫn tham gia.

Steven D'Aprano

Ngoài ra, bạn nên cho chúng tôi biết công cụ này được gọi là gì, không chỉ mô tả nó

Nó được gọi là "Watson', nhưng nó sẽ không thực sự hữu ích cho bạn vì nó là một công cụ nội bộ tại $dayjob

Steven D'Aprano

Chà, không, chỉ xóa danh sách không xóa các tham chiếu đến các lớp. Thiết kế này có vẻ như có ít nhất bốn tham chiếu đến từng đối tượng lớp

  1. đối tượng lớp được tạo bởi
    type[a] == type[d] == type[g]
    
    0ing nguồn, mà tôi sẽ gọi là “C”;
  2. tham chiếu đến C trong danh sách;
  3. tham chiếu đến C được giữ bởi mọi phiên bản của C
  4. nếu có bất kỳ lớp con nào của C, thì mỗi lớp con đó cũng giữ các tham chiếu trở lại C
  1. Vâng
  2. Vâng
  3. không có phiên bản trực tiếp nào xung quanh;
  4. không có lớp con

Steven D'Aprano

Tôi sẽ cho rằng cái đầu tiên được tạo trong một số loại đối tượng không gian tên tạm thời hoặc cục bộ, sẵn sàng để thu gom rác

Đó sẽ là một điều tốt, nhưng nó không phải là trường hợp hiện tại. Tôi không biết rằng điều này có thể thực hiện được cho đến khi tôi đọc câu trả lời của bạn, vì vậy tôi sẽ thử nghiệm nó vì sự cô lập mà nó mang lại sẽ có lợi. Một mối lo ngại là các lớp này là các lớp con của một lớp tồn tại trong không gian tên mô-đun hiện có, do đó lớp đó sẽ phải khả dụng trong thời gian

type[a] == type[d] == type[g]
0

Phần còn lại của bài đăng của bạn có ý nghĩa với tôi, nhưng không phải là mục tiêu ở đây. những thay đổi có trong các phiên bản mới được tải của các lớp không cần phải truyền ngược vào bất kỳ phiên bản hiện có nào. Các phiên bản mới sẽ được tạo từ các lớp mới được tải và mọi phiên bản trước đó [và các lớp của chúng] vẫn còn trong bộ nhớ chỉ là bộ nhớ bị lãng phí

Như tôi đã nói, thiết kế này rất 'thú vị' và có lẽ không phải là thứ tôi đã chọn nếu tôi là người tạo ra công cụ này, nhưng tại thời điểm này trong vòng đời của công cụ, việc thiết kế lại nó không có giá trị gì vì nó khó có thể xảy ra. . Hôm nay, tôi tập trung vào việc giải quyết các lỗi ngắn hạn và các cải tiến nhỏ để hỗ trợ các thay đổi quy trình kinh doanh ở phạm vi nhỏ

Tôi sẽ thử nghiệm đánh dấu tất cả các lớp hiện có là 'lỗi thời' trước khi bắt đầu một chu kỳ tải lớp mới, và sau đó khi danh sách lớp được lặp lại để tạo các thể hiện, tôi sẽ bỏ qua những lớp được đánh dấu là 'lỗi thời

À, tôi đã hiểu sai nhận xét của bạn về các lớp cha và lớp con để hiểu rằng có thể có các lớp con của các lớp được tải exec

Nhưng bạn cũng nói

“Tôi khá chắc chắn rằng nếu tôi làm vậy thì trên thực tế các đối tượng sẽ không bị xóa, bởi vì có những tham chiếu khác đến chúng ở những nơi khác trong trình thông dịch. ”

Nếu không có lớp con và không có trường hợp nào, bạn đang đề cập đến những nơi nào khác? . ]

Đó sẽ là một điều tốt, nhưng nó không phải là trường hợp hiện tại. tôi đã không

biết rằng điều này là có thể cho đến khi tôi đọc câu trả lời của bạn, vì vậy tôi sẽ

thử nghiệm với nó vì sự cô lập mà nó mang lại sẽ có lợi

Một mối lo ngại là các lớp này là các lớp con của một lớp tồn tại trong không gian tên mô-đun hiện có, do đó lớp đó sẽ phải khả dụng trong thời gian

type[a] == type[d] == type[g]
0

Có lẽ các tệp nguồn có thứ gì đó giống như


ns = {'ParentClass': ParentClass}

exec[source, ns, ns]

0 trước khi phân lớp ParentClass, phải không?

Nếu không, bạn có thể làm điều này

________số 8

những thay đổi có trong các phiên bản mới được tải của các lớp không cần phải truyền ngược vào bất kỳ phiên bản hiện có nào

Sau đó, tôi phải thừa nhận tôi không hiểu vấn đề. Trước đó bạn đã nói

“Cụ thể là, nếu một trong các lớp được đổi tên hoặc một trong các lớp bị xóa, nó sẽ vẫn nằm trong bộ nhớ trong trình thông dịch và khi lớp cha quay vòng qua tất cả các lớp con, nó sẽ được đăng ký lại. ”

Có lẽ bạn có thể làm rõ ý của bạn bằng cách đạp xe qua các lớp con?

Xin lỗi vì phản hồi chậm trễ, tôi thấy rõ ràng rằng việc đăng một ví dụ tối thiểu về cách thức hoạt động của mã hiện tại sẽ làm gián đoạn phần lớn cuộc trò chuyện này và tôi đã không thể làm điều đó cho đến hôm nay. Vui lòng hiểu khi đọc phần này rằng tôi hoàn toàn hiểu rằng mã không được viết đặc biệt tốt và ngay cả ví dụ nhỏ này cũng có thể được cải thiện đáng kể;

Tôi cũng đã bỏ qua gần như toàn bộ mã liên quan đến việc xử lý các yêu cầu

Đầu tiên, lớp cơ sở và các chức năng phụ trợ của nó

type[a] == type[d] == type[g]
1

Thứ hai, một ví dụ về tệp nguồn plugin 'quy tắc' [lưu ý rằng không có mục nhập nào cả, tệp dự kiến ​​sẽ là phiên bản 30 với bộ thông dịch viên hiện có của trình thông dịch]

type[a] == type[d] == type[g]
2

Với điều này, bạn có thể thấy rằng nếu


ns = {'ParentClass': ParentClass}

exec[source, ns, ns]

3 có mặt trong kho lưu trữ vào lần đầu tiên mà

ns = {'ParentClass': ParentClass}

exec[source, ns, ns]

4 được gọi, nhưng không có mặt ở lần thứ hai nó được gọi, thì

ns = {'ParentClass': ParentClass}

exec[source, ns, ns]

3 sẽ vẫn được liệt kê trong từ điển

ns = {'ParentClass': ParentClass}

exec[source, ns, ns]

6 và sẽ được 'đăng ký' lại dưới dạng . Vào thời điểm đó, không có trường hợp nào của

ns = {'ParentClass': ParentClass}

exec[source, ns, ns]

3 [các trường hợp duy nhất từng tồn tại được tạo bên trong vòng lặp for trong

ns = {'ParentClass': ParentClass}

exec[source, ns, ns]

8 và sau đó được để lại cho GC dọn dẹp khi vòng lặp đó thoát ra] và cũng không có lớp con nào của

ns = {'ParentClass': ParentClass}

exec[source, ns, ns]

3. Các tham chiếu duy nhất còn lại đến

ns = {'ParentClass': ParentClass}

exec[source, ns, ns]

3 là những tham chiếu thuộc sở hữu của chính trình thông dịch và giả thuyết ban đầu của tôi [phần 'xấu xa'] là tôi cần phải loại bỏ các tham chiếu đó bằng cách nào đó.

Thay vào đó, bây giờ tôi đang đề xuất rằng trong

type[a] == type[d] == type[g]
11, tôi sẽ lặp lại danh sách các đối tượng lớp và đặt thuộc tính
type[a] == type[d] == type[g]
12 cho mỗi đối tượng; . Điều này vẫn để lại đối tượng lớp trong bộ nhớ, tiêu tốn bộ nhớ, nhưng đó không phải là mối quan tâm đáng kể vào lúc này

Cảm ơn, một ví dụ tối thiểu thực sự hữu ích

Có một số điều nhỏ về phong cách tôi sẽ thay đổi, nhưng thay đổi đầu tiên tôi sẽ thực hiện là thay đổi

type[a] == type[d] == type[g]
13 để kiểm tra đối tượng có phải là một lớp con RulesSet trước khi gọi register

Tại sao?

Bạn không bao giờ biết khi nào một số thay đổi khác đối với mã của bạn sẽ tạo ra một biến toàn cục bao gồm phương thức

type[a] == type[d] == type[g]
17 và ai biết điều đó sẽ làm gì?

type[a] == type[d] == type[g]
8

Tôi hy vọng điều đó sẽ an toàn hơn nhiều và cũng có thể nhanh hơn

[Tất nhiên nó giả sử tất cả các lớp quy tắc của bạn là các lớp con của RulesSet. ]

Nếu thay đổi đó không phá vỡ các bài kiểm tra của bạn, đã đến lúc chuyển sang thay đổi lớn hơn

type[a] == type[d] == type[g]
9

Tôi nghĩ rằng điều này sẽ giải quyết vấn đề của bạn

Giả sử điều đó không phá vỡ bất cứ điều gì, bước tiếp theo là tránh sử dụng các toàn cầu thực tế làm không gian tên cho exec, nhưng điều đó [tôi nghĩ] có khả năng bị phá vỡ cao hơn và nếu công cụ này dự kiến ​​​​sẽ ngừng hoạt động sau một năm nữa thì có thể

Xóa hoạt động như thế nào trong Python?

Định nghĩa và cách sử dụng . Trong Python, mọi thứ đều là một đối tượng, do đó, từ khóa del cũng có thể được sử dụng để xóa các biến, danh sách hoặc một phần của danh sách, v.v. The del keyword is used to delete objects. In Python everything is an object, so the del keyword can also be used to delete variables, lists, or parts of a list etc.

Python có tự động xóa các đối tượng không?

Python tự động xóa các đối tượng không cần thiết [các loại hoặc thể hiện lớp tích hợp sẵn] để giải phóng không gian bộ nhớ . Quá trình Python thu hồi định kỳ các khối bộ nhớ không còn được sử dụng nữa được gọi là Bộ sưu tập rác.

Làm thế nào các đối tượng bị xóa trong Python?

Sử dụng phương thức __del__[] . Trong Python, hàm hủy được xác định bằng hàm cụ thể __del__[]. Chẳng hạn, khi chúng ta chạy del object name, hàm hủy của đối tượng sẽ tự động được gọi và sau đó nó sẽ được thu gom rác.

Làm cách nào để xóa một tệp trong Python?

Có nhiều cách để Xóa tệp trong Python nhưng những cách tốt nhất là như sau. .
hệ điều hành. remove[] xóa một tập tin
hệ điều hành. unlink[] xóa một tập tin. nó là tên Unix của phương thức remove[]
đóng cửa. rmtree[] xóa một thư mục và tất cả nội dung của nó
đường dẫn. Con đường

Chủ Đề