পাইথন ২.6-তে ইউনিকোড_লাইটারাল ব্যবহার করে কোনও গ্যাটাচস?


101

পাইথন ২.6 এর অধীনে আমরা ইতিমধ্যে আমাদের কোড বেসটি পেয়েছি। পাইথন 3.0.০ এর জন্য প্রস্তুত করার জন্য, আমরা যুক্ত করা শুরু করেছি:

__ ভবিষ্যত__ থেকে ইউনিকোড_লাইটারালগুলি আমদানি করুন

আমাদের .pyফাইলগুলিতে (যেমন আমরা তাদের সংশোধন করি) আমি ভাবছি যে অন্য কেউ এটি করে চলেছে এবং কোনও অ-সুস্পষ্ট গ্যাচচায় প্রবেশ করেছে (সম্ভবত অনেক সময় ডিবাগ করার পরে)।

উত্তর:


101

ইউনিকোড স্ট্রিংয়ের সাথে কাজ করার সমস্যার মূল উত্স হ'ল আপনি যখন ইউনিকোডের সাথে utf-8 এনকোডযুক্ত স্ট্রিংগুলি মিশ্রিত করেন।

উদাহরণস্বরূপ, নিম্নলিখিত স্ক্রিপ্টগুলি বিবেচনা করুন।

two.py

# encoding: utf-8
name = 'helló wörld from two'

one.py

# encoding: utf-8
from __future__ import unicode_literals
import two
name = 'helló wörld from one'
print name + two.name

চলমান আউটপুট python one.pyহয়:

Traceback (most recent call last):
  File "one.py", line 5, in <module>
    print name + two.name
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 4: ordinal not in range(128)

এই উদাহরণে, two.nameএকটি utf-8 এনকোড স্ট্রিং (ইউনিকোড নয়) যেহেতু এটি আমদানি করে নি unicode_literals, এবং one.nameএটি একটি ইউনিকোড স্ট্রিং। আপনি উভয় মিশ্রন করলে পাইথন এনকোডযুক্ত স্ট্রিংটি ডিকোড করার চেষ্টা করে (এটি আসকি বলে ধরে নিচ্ছে) এবং এটি ইউনিকোডে রূপান্তরিত করে এবং ব্যর্থ হয়। আপনি যদি এটি কাজ করবে print name + two.name.decode('utf-8')

আপনি যদি কোনও স্ট্রিং এনকোড করে পরে মিশ্রিত করার চেষ্টা করেন তবে একই জিনিস ঘটতে পারে। উদাহরণস্বরূপ, এটি কাজ করে:

# encoding: utf-8
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
    html = html.encode('utf-8')
print 'DEBUG: %s' % html

আউটপুট:

DEBUG: <html><body>helló wörld</body></html>

তবে যুক্ত করার পরে import unicode_literalsএটি হয় না:

# encoding: utf-8
from __future__ import unicode_literals
html = '<html><body>helló wörld</body></html>'
if isinstance(html, unicode):
    html = html.encode('utf-8')
print 'DEBUG: %s' % html

আউটপুট:

Traceback (most recent call last):
  File "test.py", line 6, in <module>
    print 'DEBUG: %s' % html
UnicodeDecodeError: 'ascii' codec can't decode byte 0xc3 in position 16: ordinal not in range(128)

এটি ব্যর্থ হয়েছে কারণ 'DEBUG: %s'একটি ইউনিকোড স্ট্রিং এবং তাই অজগরটি ডিকোড করার চেষ্টা করে html। মুদ্রণ ঠিক করার বেশ কয়েকটি উপায় হয় হয় print str('DEBUG: %s') % htmlবা হয় print 'DEBUG: %s' % html.decode('utf-8')

আমি আশা করি ইউনিকোড স্ট্রিং ব্যবহার করার সময় এটি আপনাকে সম্ভাব্য গোটাচগুলি বুঝতে সহায়তা করে।


11
আমি decode()সমাধানগুলির str()বা সমাধানগুলির পরিবর্তে সমাধানগুলির সাথে যেতে পরামর্শ দেব encode(): আপনি যত বেশি ঘন ঘন ইউনিকোড অবজেক্ট ব্যবহার করেন, কোডটি পরিষ্কার হয়, আপনি যা চান তা হ'ল বাহ্যিকভাবে আবদ্ধ এনকোডিং সহ বাইটের অ্যারেগুলি নয় not
এরিক হে লেবিগোট

8
দয়া করে আপনার পরিভাষা ঠিক করুন। when you mix utf-8 encoded strings with unicode onesইউটিএফ -8 এবং ইউনিকোড 2 টি পৃথক এনকোডিং নয়; ইউনিকোড একটি স্ট্যান্ডার্ড এবং ইউটিএফ -8 হ'ল এনকোডিংগুলির মধ্যে একটি এটি সংজ্ঞায়িত করে।
কোস

11
@ কোস: আমি মনে করি তার অর্থ ইউনিকোড (তাই ডিকোডড) অবজেক্টের সাথে "utf-8 এনকোডযুক্ত স্ট্রিং" অবজেক্টগুলি মিশ্রিত করা । পূর্বেরটি টাইপের হয় , পরেরটি টাইপ হয় । বিভিন্ন অবজেক্ট হওয়ার কারণে সমস্যাটি দেখা দিতে পারে যদি আপনি তাদের যোগ / সংমিশ্রণ / ইন্টারপোলেট করার চেষ্টা করেনstrunicode
MestreLion

এটি কি প্রযোজ্য python>=2.6নাকি python==2.6?
joar

16

২.6-তে (অজগর 2.6.5 এর আগে আরসি 1+) ইউনিকোড লিটারাল কীওয়ার্ড আর্গুমেন্ট ( ইস্যু 4978 ) দিয়ে ভাল খেলেন না :

উদাহরণস্বরূপ নীচের কোডটি ইউনিকোড_লাইটালালগুলি ব্যতীত কাজ করে keywords must be stringতবে প্রকারের সাথে ব্যর্থ হয়: যদি ইউনিকোড_লাইটারাল ব্যবহার করা হয়।

  >>> def foo(a=None): pass
  ...
  >>> foo(**{'a':1})
  Traceback (most recent call last):
    File "<stdin>", line 1, in <module>
      TypeError: foo() keywords must be strings

17
ঠিক এফওয়াইআই, পাইথন ২.6.৫ আরসি 1 এটি স্থির করেছে।
মাহমুদ আবদেলকাদের

13

আমি খুঁজে পেয়েছি যে আপনি যদি unicode_literalsনির্দেশনা যুক্ত করেন তবে আপনারও এমন কিছু যুক্ত করা উচিত:

 # -*- coding: utf-8

আপনার .py ফাইলটি প্রথম বা দ্বিতীয় লাইনে। অন্যথায় লাইন যেমন:

 foo = "barré"

একটি ত্রুটির ফলে যেমন:

সিনট্যাক্স এরির: ১৯ line লাইনে নকল-পিপি ফাইলটিতে নন-এসসিআইআই অক্ষর '\ xc3',
 তবে কোনও এনকোডিং ঘোষিত হয়নি; http://www.python.org/peps/pep-0263.html দেখুন
 বিস্তারিত জানার জন্য

5
@ আইয়ানম্যাকিনন: পাইথন 3 অনুমান করে যে ফাইলগুলি ডিফল্টরূপে ইউটিএফ
এন্ডোলিথ

3
@ এন্ডোলিথ: তবে পাইথন 2 এটি করে না, এবং যদি আপনি মন্তব্যগুলিতে অ-এসকি চরগুলি ব্যবহার করেন তবে এটি সিনট্যাক্স ত্রুটিটি দেবে ! সুতরাং আইএমএইচও # -*- coding: utf-8হ'ল কার্যত বাধ্যতামূলক বিবৃতি আপনি যদি ব্যবহার করেন unicode_literalsবা না করেন তবে
MestreLion

-*-প্রয়োজন হয় না; আপনি যদি ইমাস-সামঞ্জস্যপূর্ণ পথে যাচ্ছিলেন তবে আমার মনে হয় আপনার প্রয়োজন হবে -*- encoding: utf-8 -*-( -*-শেষেও দেখুন)। আপনার যা দরকার তা হ'ল coding: utf-8(বা তার =পরিবর্তে : )।
ক্রিস মরগান

2
আপনি এই ত্রুটিটি পেয়ে যান বা না থাকুন from __future__ import unicode_literals
ফ্লিম

3
ইমাস সামঞ্জস্যের জন্য # -*- coding: utf-8 -*- "কোডিং" ("এনকোডিং" বা "ফাইলেনকোডিং" বা অন্য কিছু নয় - পাইথন কেবল কোনও উপসর্গ নির্বিশেষে "কোডিং" সন্ধান করে) প্রয়োজন।
অ্যালেক্স ডুপুয়

7

এছাড়াও যে অ্যাকাউন্টটি নিতে unicode_literalপ্রভাবিত করবে eval()কিন্তু না repr()(একটি অসম আচরণ যা এই প্রোগ্রামটিতে একটি বাগ), অর্থাৎ eval(repr(b'\xa4'))সমান হবে না b'\xa4'(যেমন পাইথন 3 হবে)।

আদর্শভাবে, নীচের কোডটি একটি আক্রমণকারী হবে, যা সবসময় কাজ করা উচিত, unicode_literalsএবং পাইথন {2.7, 3.x} ব্যবহারের সমস্ত সংমিশ্রণের জন্য :

from __future__ import unicode_literals

bstr = b'\xa4'
assert eval(repr(bstr)) == bstr # fails in Python 2.7, holds in 3.1+

ustr = '\xa4'
assert eval(repr(ustr)) == ustr # holds in Python 2.7 and 3.1+

দ্বিতীয় দৃ ser়তা পাইথন ২.7- repr('\xa4')তে মূল্যায়ন করার পরে, কাজটি ঘটে u'\xa4'


2
আমি মনে করি যে এখানে বড় সমস্যাটি আপনি ব্যবহার করছেন repr কোনও বস্তুর পুনঃজেনার করতে । reprডকুমেন্টেশন পরিষ্কারভাবে বলে যে, এই হল না প্রয়োজন। আমার মতে, এটি reprকেবল ডিবাগিংয়ের জন্য দরকারী কিছুতে প্রেরণা দেয়।
jpmc26

5

আরো আছে.

এমন লাইব্রেরি এবং বিল্টিন রয়েছে যা ইউনিকোড সহ্য করে না এমন স্ট্রিংগুলি প্রত্যাশা করে।

দুটি উদাহরণ:

builtin:

myenum = type('Enum', (), enum)

(সামান্য এ্যাসোটিক) ইউনিকোড_লিটালালগুলি নিয়ে কাজ করে না: টাইপ () স্ট্রিংয়ের প্রত্যাশা করে।

গ্রন্থাগার:

from wx.lib.pubsub import pub
pub.sendMessage("LOG MESSAGE", msg="no go for unicode literals")

কাজ করে না: ডাব্লুএক্স পাবসাব লাইব্রেরি একটি স্ট্রিং বার্তার প্রকার আশা করে।

প্রাক্তনটি গুপ্ত এবং সহজেই এটির সাথে স্থির

myenum = type(b'Enum', (), enum)

তবে আপনার কোডটি pub.sendMessage () আমার (যা আমার) তে কলগুলি পূর্ণ থাকলে পরেটি সর্বনাশা।

এটা ডাং, এহ?!?


3
এবং টাইপ স্টাফগুলি মেটাচ্লাসগুলিতেও ফাঁস হয় - সুতরাং জাঙ্গোতে আপনি যে কোনও স্ট্রিং ঘোষণা করেছেন তা class Meta:হওয়া উচিতb'field_name'
হামিশ ডাউনার

2
হ্যাঁ ... আমার ক্ষেত্রে আমি বুঝতে পেরেছিলাম যে সমস্ত 'সেন্ড ম্যাসেজ স্ট্রিং বি' সংস্করণ সহ অনুসন্ধান এবং প্রতিস্থাপনের প্রচেষ্টা মূল্যবান। আপনি যদি ভয়ঙ্কর "ডিকোড" ব্যতিক্রম এড়াতে চান তবে আপনার প্রোগ্রামটিতে ইউনিকোডকে কঠোরভাবে ব্যবহার করা, প্রয়োজনীয় হিসাবে ইনপুট এবং আউটপুটকে রূপান্তর করার মতো কিছুই নেই ("আমি ইউনিকোড স্যান্ডউইচ" উল্লেখ করেছি কিছু প্রবন্ধে আমি বিষয়টিতে পড়েছি)। সামগ্রিকভাবে, ইউনিকোড_সামগ্রী আমার পক্ষে বড় জয় ...
গ্রিনএজজেড

0

আপনিfrom __future__ import unicode_literals যেখানেই ব্যবহার করেন এমন কোনও মডিউল আমদানি করা হলে ক্লিক সমস্ত স্থানটিতে ইউনিকোড ব্যতিক্রম বাড়িয়ে তুলবেclick.echo । এটি একটি দুঃস্বপ্ন ...

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.