2009-04-02 1 views
8

Tôi đang chạy Python 2.4 trong một công cụ trò chơi và tôi muốn có thể tắt tất cả các bản in nếu cần. Ví dụ tôi muốn có các bản in trên cho một xây dựng gỡ lỗi, và sau đó tắt cho một xây dựng phát hành. Điều bắt buộc là nó càng minh bạch càng tốt.Cách tốt nhất để chuyển đổi các bản in python là gì?

Giải pháp của tôi cho điều này trong mã C của động cơ là có hàm printf bên trong macro vararg và xác định rằng không làm gì trong bản dựng.

Đây là giải pháp hiện tại của tôi:

DebugPrints = True 
def PRINT (*args): 
    global DebugPrints 
    if DebugPrints: 
     string = "" 
     for arg in args: 
      string += " " + str(arg) 
     print string 

Nó làm cho nó dễ dàng để chuyển đổi outs in, nhưng có thể là một cách tốt hơn để định dạng chuỗi. Vấn đề chính của tôi là điều này thực sự đang bổ sung thêm nhiều cuộc gọi hàm vào chương trình.

Tôi tự hỏi liệu có bất kỳ điều gì bạn có thể làm để từ khóa hoạt động như thế nào không?

+0

thay cho vòng lặp for, bạn có thể sử dụng 'print "" .join (args)' –

+0

oops, mà cần phải có được in "" .join (bản đồ (str, args)) –

+0

Vẫn sử dụng 2.4? –

Trả lời

12

có, bạn có thể chỉ định sys.stdout cho bất kỳ điều gì bạn muốn. Tạo một lớp nhỏ với một phương pháp write mà không làm gì:

class DevNull(object): 
    def write(self, arg): 
     pass 

import sys  
sys.stdout = DevNull() 
print "this goes to nirvana!" 

Với kỹ thuật tương tự bạn cũng có thể đã in của bạn đăng nhập vào một tập tin bằng cách thiết lập sys.stdout đến một đối tượng tập tin mở.

+0

Đừng quên sao lưu 'sys.stdout nếu bạn muốn kích hoạt lại nó sau này. _stdout = sys.stdout; sys.stdout = DevNull() –

+0

Với các mô đun như "đăng nhập", phương pháp này có vẻ hơi vô lý. –

+0

'vô lý' là một chút trên đầu nhưng tôi nhận được quan điểm của bạn. Tôi nên đặt tên câu hỏi là 'cách dễ nhất để chuyển đổi bản in', có thể? –

3

Không sử dụng in, nhưng tạo một lớp bảng điều khiển xử lý tất cả in. Chỉ cần thực hiện cuộc gọi đến bàn điều khiển và bảng điều khiển có thể quyết định có thực sự in chúng hay không. Một lớp giao diện điều khiển cũng hữu ích cho những thứ như thông báo lỗi và cảnh báo hoặc chuyển hướng nơi đầu ra đi.

+0

+1: sử dụng ghi nhật ký hoặc cuộn của riêng bạn. Nhưng không sử dụng in. –

+0

Vâng, mô-đun đăng nhập hiện có đáng xem. Tùy thuộc vào phạm vi của dự án, một lớp nhỏ có thể là đủ. –

+0

Mô đun ghi nhật ký tích hợp khá tốt. –

8

Các logging module là cách "tốt nhất" .. mặc dù tôi khá thường xuyên chỉ cần sử dụng một cái gì đó đơn giản như ..

class MyLogger: 
    def _displayMessage(self, message, level = None): 
     # This can be modified easily 
     if level is not None: 
      print "[%s] %s" % (level, message 
     else: 
      print "[default] %s" % (message) 

    def debug(self, message): 
     self._displayMessage(message, level = "debug") 
    def info(self, message): 
     self._displayMessage(message, level = "info") 

log = MyLogger() 
log.info("test") 
10

Tôi biết một câu trả lời đã được đánh dấu là chính xác, nhưng Python có một lá cờ debug mà cung cấp một giải pháp sạch hơn. Bạn sử dụng nó như thế này:

if __debug__: 
    print "whoa" 

Nếu bạn gọi Python với -O hoặc -OO (như bình thường cho một thông cáo xây dựng), __debug__ được thiết lập để False. Điều thậm chí còn tốt hơn là __debug__ là một trường hợp đặc biệt cho thông dịch viên; nó sẽ thực sự loại bỏ mã đó khi nó viết các tệp pyc/pyo, làm cho mã kết quả nhỏ hơn/nhanh hơn. Lưu ý rằng bạn không thể gán giá trị cho __debug__, do đó, nó hoàn toàn dựa trên các đối số dòng lệnh đó.

+0

+1: Điều đó rất hữu ích để biết, ngay cả khi nỗ lực của nó nhiều hơn một chút để thực hiện –

+0

Đó là một loại xấu hổ cờ gỡ lỗi được bật khi bạn chỉ cần làm python ./thescript.py (thay vì sử dụng cờ gỡ lỗi -d) – dbr

0

Tôi đã trả lời câu hỏi này trên different post nhưng được các câu hỏi được đánh dấu trùng lặp:

dù sao đi nữa, đây là những gì tôi sẽ làm:

from __future__ import print_function 
DebugPrints = 0 

def print(*args, **kwargs): 
    if DebugPrints: 
     return __builtins__.print(*args, **kwargs) 

print('foo') # doesn't get printed 
DebugPrints = 1 
print('bar') # gets printed 

buồn bã bạn không thể giữ cho cú pháp py2 in print 'foo'

+0

Hoạt động tốt. Nhưng làm thế nào để chức năng in biết về 'enable_print', nếu nó không phải là toàn cầu và không được thông qua như một đối số? – Pyderman

1

Nếu bạn thực sự muốn chuyển in:

>>> import sys 
>>> import os 
>>> print 'foo' 
foo 
>>> origstdout = sys.stdout 
>>> sys.stdout = open(os.devnull, 'w') 
>>> print 'foo' 
>>> sys.stdout = origstdout 
>>> print 'foo' 
foo 

Tuy nhiên, tôi khuyên bạn chỉ nên sử dụng print để lấy mã số. Sử dụng logging cho các ứng dụng thực như câu hỏi gốc mô tả.Nó cho phép cho một quy mô trượt của độ dài, vì vậy bạn có thể chỉ có việc ghi nhật ký quan trọng, hoặc ghi nhật ký chi tiết hơn về các chi tiết thường ít quan trọng hơn.

>>> import logging 
>>> logging.basicConfig(level=logging.DEBUG) 
>>> logging.debug('foo') 
DEBUG:root:foo 

Ví dụ: sử dụng có thể là đặt nhật ký gỡ lỗi trong suốt mã của bạn. Sau đó, để bịt miệng họ, thay đổi mức độ của bạn đến một cấp độ cao hơn, một trong những INFO, WARN hoặc WARNING, ERROR, hoặc CRITICAL hoặc FATAL

>>> logging.root.setLevel(logging.INFO) 
>>> logging.debug('foo') 
>>> 

Trong một kịch bản bạn sẽ muốn chỉ cần thiết lập này trong basicConfig như thế này :

import logging 
logging.basicConfig(level=logging.INFO) 

logging.debug('foo') # this will be silent 

Sử dụng ghi nhật ký phức tạp hơn có thể tìm thấy in the docs.