2009-02-15 33 views
35

Tôi có thể quá tải chức năng print và gọi chức năng bình thường từ bên trong không? Những gì tôi muốn làm là sau một dòng cụ thể tôi muốn print để gọi số print của tôi sẽ gọi số print bình thường và ghi một bản sao vào tệp.Quá tải python in

Ngoài ra tôi không biết cách quá tải print. Tôi không biết làm thế nào để làm đối số chiều dài biến. Tôi sẽ tìm kiếm nó sớm nhưng overload print python chỉ nói với tôi tôi không thể quá tải print trong 2.x đó là những gì tôi đang sử dụng.

Trả lời

2

Trong Python 2.x bạn không thể, vì in không phải là một hàm, đó là một câu lệnh. Trong Python 3 in là một chức năng, vì vậy tôi cho rằng nó có thể được ghi đè (mặc dù đã không thử nó).

31

Quá tải print là tính năng thiết kế của python 3.0 để giải quyết sự thiếu khả năng của bạn để làm như vậy trong python 2.x.

Tuy nhiên, bạn có thể ghi đè lên sys.stdout. (example.) Chỉ cần gán nó cho một đối tượng giống như tệp khác thực hiện những gì bạn muốn.

Ngoài ra, bạn có thể chỉ cần tập lệnh của bạn thông qua lệnh unix tee. python yourscript.py | tee output.txt sẽ in ra cả stdout và output.txt, nhưng điều này sẽ bắt tất cả đầu ra.

3

Mặc dù bạn không thể thay thế từ khóa print (bằng Python 2.x print là từ khóa), thực tế phổ biến là thay thế sys.stdout để làm điều gì đó tương tự như print ghi đè; ví dụ, với một thể hiện của StringIO.StringIO. Điều này sẽ nắm bắt tất cả các dữ liệu được in trong cá thể StringIO, sau đó bạn có thể thao tác nó.

10

Tôi gặp phải vấn đề tương tự.

Làm thế nào về điều này:

class writer : 
    def __init__(self, *writers) : 
     self.writers = writers 

    def write(self, text) : 
     for w in self.writers : 
      w.write(text) 

import sys 

saved = sys.stdout 
fout = file('out.log', 'w') 
sys.stdout = writer(sys.stdout, fout) 
print "There you go." 
sys.stdout = saved 
fout.close() 

Nó làm việc như một nét duyên dáng cho tôi. Nó được lấy từ http://mail.python.org/pipermail/python-list/2003-February/188788.html

+3

'saved = sys.stdout' là không cần thiết,' sys .__ stdout__' luôn giữ nguyên 'stdout', do đó, ở cuối chỉ cần' sys.stdout = sys .__ stdout__'. – chown

+0

lưu sys.stdout cho phép bạn ghi đè chuỗi; nếu bạn viết thẳng vào sys .__ stdout__ bạn sẽ bỏ qua bất kỳ khung công tác ghi nhật ký nào hoặc bạn thử và tiêm vào chương trình. Tốt nhất của nó để tiết kiệm một cách rõ ràng giá trị trước của stdout. – Will

+0

Có lý do cụ thể nào bạn mở nhật ký bằng cách sử dụng 'file()' thay vì 'open()'? [Tài liệu đề nghị chống lại điều đó.] (Https://docs.python.org/2/library/functions.html#file) – Eric

1

tôi trả lời cùng một câu hỏi on a different SO question

Về cơ bản, giải pháp đơn giản nhất là chỉ cần chuyển hướng đầu ra để thiết bị lỗi chuẩn như sau, trong file wsgi config.

50

Đối với những người xem lại câu trả lời trước đây, kể từ khi phát hành phiên bản "Python 2.6", có câu trả lời mới cho câu hỏi của người đăng ban đầu.

Trong Python 2.6 trở lên, bạn có thể vô hiệu hóa các tuyên bố in có lợi cho chức năng in, và sau đó ghi đè lên các chức năng in với chức năng in của riêng bạn:

from __future__ import print_function 
# This must be the first statement before other statements. 
# You may only put a quoted or triple quoted string, 
# Python comments, other future statements, or blank lines before the __future__ line. 

try: 
    import __builtin__ 
except ImportError: 
    # Python 3 
    import builtins as __builtin__ 

def print(*args, **kwargs): 
    """My custom print() function.""" 
    # Adding new arguments to the print function signature 
    # is probably a bad idea. 
    # Instead consider testing if custom argument keywords 
    # are present in kwargs 
    __builtin__.print('My overridden print() function!') 
    return __builtin__.print(*args, **kwargs) 

Tất nhiên bạn sẽ cần phải xem xét rằng chức năng in này chỉ là mô-đun rộng tại thời điểm này. Bạn có thể chọn ghi đè __builtin__.print nhưng bạn cần phải lưu số __builtin__.print gốc; có khả năng mucking với không gian tên __builtin__.

+0

Nếu tôi thử sử dụng hàm này trong Python 2.7.3, tôi nhận được một dòng '7, trong bản in return __builtins __. Print (* args, ** kwargs) AttributeError: đối tượng 'dict' không có lỗi 'print'' thuộc tính. Điều gì có thể là vấn đề? – loudandclear

+0

Hmmm ... Tôi đã thử nghiệm nó với Python 2.7.2 và nó hoạt động. Tôi đã nhận thấy Python 2.7.4 vừa được phát hành và có một vài sửa lỗi với _ _future _ _ và print_function Kiểm tra http://hg.python.org/cpython/file/9290822f2280/Misc/NEWS Tôi chưa thử nghiệm 2.7.4. – DevPlayer

+2

Bạn nên làm 'import __builtin__' và sau đó' __builtin __. Print' thay vì sử dụng '__builtins__', [xem giải thích tại đây] (https://docs.python.org/2/reference/executionmodel.html). – rczajka

8
class MovieDesc: 
    name = "Name" 
    genders = "Genders" 
    country = "Country" 

def __str__(self): 
#Do whatever you want here 
     return "Name: {0}\tGenders: {1} Country: {2} ".format(self.name,self.genders,self.country) 

) 
1

chỉ nghĩ rằng tôi muốn thêm ý tưởng của mình ...phù hợp với mục đích của tôi là có thể chạy sthg trong Eclipse và sau đó chạy từ (Windows) CLI mà không nhận được mã hóa ngoại lệ với mỗi bản in. Bất cứ điều gì bạn không thực hiện EncodingStdout một lớp con của tệp lớp: dòng "self.encoding = encoding" sẽ dẫn đến thuộc tính encoding là Không! NB một điều tôi phát hiện ra trong một ngày vật lộn với công cụ này là ngoại lệ mã hóa được nâng lên TRƯỚC KHI nhận được "in" hoặc "viết": đó là khi chuỗi tham số (tức là "mondodod% s blah blah% s "% (" blip "," blap ")) được tạo bởi ... cái gì ??? Cơ cấu"?

class EncodingStdout(object): 
    def __init__(self, encoding='utf-8'): 
     self.encoding = encoding 

    def write_ln(self, *args): 
     if len(args) < 2: 
      sys.__stdout__.write(args[ 0 ] + '\n') 
     else: 
      if not isinstance(args[ 0 ], basestring): 
       raise Exception("first arg was %s, type %s" % (args[ 0 ], type(args[ 0 ]))) 
      # if the default encoding is UTF-8 don't bother with encoding 
      if sys.getdefaultencoding() != 'utf-8': 
       encoded_args = [ args[ 0 ] ] 
       for i in range(1, len(args)): 
        # numbers (for example) do not have an attribute "encode" 
        if hasattr(args[ i ], 'encode'): 
         encoded_args.append(args[ i ].encode(self.encoding, 'replace')) 
        else: 
         encoded_args.append(args[ i ]) 
       args = encoded_args 
      sys.__stdout__.write(args[ 0 ] % tuple(args[ 1 : ]) + '\n') 
     # write seems to need a flush 
     sys.__stdout__.flush() 

    def __getattr__(self, name): 
     return sys.__stdout__.__getattribute__(name) 

print "=== A mondodod %s %s" % ("été", "pluviôse, irritée contre la ville entière") 


sys.stdout = EncodingStdout() 
sys.stdout.write_ln("=== B mondodod %s %s", "été", "pluviôse, irritée contre la ville entière") 

# convenience method 
def pr(*args): 
    sys.stdout.write_ln(*args) 

pr("=== C mondodod %s %s", "été", "pluviôse, irritée contre la ville entière") 
1

Đối với một ví dụ rất đơn giản, tính đến Python3.4 (chưa được thử nghiệm với các phiên bản cũ) hoạt động này tốt cho tôi (đặt ở phía trên của mô-đun):

def dprint(string): 
    __builtins__.print("%f -- %s" % (time.time(), string)) 

print = dprint 

Lưu ý, đây chỉ hoạt động nếu tham số chuỗi là một str ... YMMV