`1 ..__ truediv__` কী? পাইথনের কি একটি .. ("ডট ডট") স্বরলিপি সিনট্যাক্স রয়েছে?


190

আমি সম্প্রতি এমন একটি সিনট্যাক্স পেলাম যা আমি আগে কখনও দেখিনি যখন আমি অজগর শিখেছিলাম বা বেশিরভাগ টিউটোরিয়ালে, ..স্বরলিপিটি দেখে মনে হয় এটির মতো:

f = 1..__truediv__ # or 1..__div__ for python 2

print(f(8)) # prints 0.125 

আমি বুঝতে পেরেছিলাম যে এটি হুবহু একই ছিল (অবশ্যই এটি দীর্ঘতর ব্যতীত):

f = lambda x: (1).__truediv__(x)
print(f(8)) # prints 0.125 or 1//8

তবে আমার প্রশ্নগুলি হ'ল:

  • কীভাবে এটি করতে পারে?
  • এটি দুটি বিন্দুর সাথে আসলে কী বোঝায়?
  • কীভাবে আপনি এটি আরও জটিল বিবৃতিতে ব্যবহার করতে পারেন (সম্ভব হলে)?

এটি সম্ভবত ভবিষ্যতে আমার অনেক লাইন কোড সংরক্ষণ করবে ... :)


14
নোট: (1).__truediv__যেমন সত্যিই একই নয় 1..__truediv__সাবেক কল হিসাবে, int.__truediv__যখন আধুনিক করে float.__truediv__। বিকল্পভাবে, আপনি 1 .__truediv__(একটি স্থান সহ) ব্যবহার করতে পারেন
to

7
লক্ষ্য করুন 1//8হয় 0না, 0.125, পাইথন উভয় সংস্করণে।
mkrieger1

1
স্মরণ করিয়ে দেয়if (x <- 3) {...}
ডুনো

7
এখানে এটি ব্যবহারের একটি উদাহরণ।
মোন অলিভ

3
@ কিথসি উচ্চ মানের উত্তর এবং মন্তব্যগুলি দেখায় যে নমুনা কোডটি বোঝার জন্য অন্তর্দৃষ্টি প্রয়োজন, অনেকের কাছেই অবাক করা, এর বিকল্প রয়েছে যা পরিষ্কার, আরও সাধারণ এবং কমপক্ষে দক্ষ। আমার প্রধান গ্রিপ হ'ল পাঠযোগ্যতার গণনা। যেখানে সবচেয়ে বেশি প্রয়োজন তার জন্য চালাকি সঞ্চয় করুন - মানুষের সাথে যোগাযোগ করুন।
পিটার উড

উত্তর:


212

আপনার যা রয়েছে তা floatশূন্যের পিছনে ছাড়াই আক্ষরিক, যা আপনি তারপরে __truediv__পদ্ধতিটি অ্যাক্সেস করতে পারেন । এটি নিজে অপারেটর নয়; প্রথম বিন্দুটি ভাসমান মানের অংশ, এবং দ্বিতীয়টি হ'ল বিন্দু অপারেটরগুলি অবজেক্টের বৈশিষ্ট্য এবং পদ্ধতিগুলি অ্যাক্সেস করতে।

নিম্নলিখিতগুলি করে আপনি একই পয়েন্টে পৌঁছতে পারেন।

>>> f = 1.
>>> f
1.0
>>> f.__floordiv__
<method-wrapper '__floordiv__' of float object at 0x7f9fb4dc1a20>

আরেকটি উদাহরণ

>>> 1..__add__(2.)
3.0

এখানে আমরা ১.০ থেকে ২.০ যোগ করি যা স্পষ্টতই 3.0 প্রদান করে।


165
সুতরাং আমরা যা পেয়েছি সে একজন দেব যিনি সামান্য বংশবৃদ্ধির জন্য অনেক স্পষ্টতার ত্যাগ করেছিলেন এবং আমরা এখানে।
টেম্পোরাল

11
হতে পারে যে কেউ তার উত্স কোড 5.5 "ফ্লপি ডিস্কে সংরক্ষণ করছে?
টমাস আইয়ুব

10
@ থমাস আইউব এটি 5.25 "
আইরিচ


2
মজাদার ঘটনা, আপনি এটি জাভাস্ক্রিপ্টেও করতে পারেন:1..toString()
ডেরেক 朕 會

74

প্রশ্নের ইতিমধ্যে যথেষ্ট উত্তর দেওয়া হয়েছে (যেমন @ পল রুনির উত্তর) তবে এই উত্তরগুলির যথার্থতা যাচাই করাও সম্ভব।

আমাকে বিদ্যমান উত্তরগুলি পুনরায় সরিয়ে ফেলতে দাও: ..এটি কোনও একক সিনট্যাক্স উপাদান নয়!

উত্স কোডটি "টোকেনাইজড" কীভাবে তা পরীক্ষা করতে পারেন । এই টোকেনগুলি কীভাবে কোডটির ব্যাখ্যা করা হয় তা উপস্থাপন করে:

>>> from tokenize import tokenize
>>> from io import BytesIO

>>> s = "1..__truediv__"
>>> list(tokenize(BytesIO(s.encode('utf-8')).readline))
[...
 TokenInfo(type=2 (NUMBER), string='1.', start=(1, 0), end=(1, 2), line='1..__truediv__'),
 TokenInfo(type=53 (OP), string='.', start=(1, 2), end=(1, 3), line='1..__truediv__'),
 TokenInfo(type=1 (NAME), string='__truediv__', start=(1, 3), end=(1, 14), line='1..__truediv__'),
 ...]

সুতরাং স্ট্রিংটি 1.সংখ্যা হিসাবে ব্যাখ্যা করা হয়, দ্বিতীয়টি .একটি ওপি (অপারেটর, এক্ষেত্রে "গুন অ্যাট্রিবিউট" অপারেটর) এবং __truediv__পদ্ধতিটির নাম। সুতরাং এটি শুধুমাত্র __truediv__ভাসা পদ্ধতি অ্যাক্সেস করা হয় 1.0

উত্পন্ন বাইকোড দেখার আরেকটি উপায় হ'ল এটি একত্র করা। এটি আসলে কিছু কোড কার্যকর করা হলে সম্পাদিত নির্দেশাবলী দেখায়: dis

>>> import dis

>>> def f():
...     return 1..__truediv__

>>> dis.dis(f)
  4           0 LOAD_CONST               1 (1.0)
              3 LOAD_ATTR                0 (__truediv__)
              6 RETURN_VALUE

যা মূলত একই কথা বলে। এটি __truediv__ধ্রুবকের বৈশিষ্ট্যটি লোড করে 1.0


আপনার প্রশ্ন সম্পর্কিত

এবং কীভাবে আপনি এটি আরও জটিল বিবৃতিতে ব্যবহার করতে পারেন (সম্ভব হলে)?

যদিও এটি সম্ভব তবে আপনার কোডটি কখনও লেখা উচিত নয় কারণ কোডটি কী করছে তা অস্পষ্ট। সুতরাং দয়া করে আরও জটিল বিবৃতিতে এটি ব্যবহার করবেন না। আমি এমনকি এতদূর যেতে চাই যে আপনি এটি এত "সরল" বিবৃতিতে ব্যবহার করবেন না, কমপক্ষে আপনার নির্দেশিকা পৃথক করতে আপনার প্রথম বন্ধনী ব্যবহার করা উচিত:

f = (1.).__truediv__

এটি অবশ্যই আরও পাঠযোগ্য হবে - তবে এর লাইনের সাথে কিছু:

from functools import partial
from operator import truediv
f = partial(truediv, 1.0)

আরও ভাল হবে!

ব্যবহার করার পদ্ধতিটি অজগরটির ডেটা মডেলও ( partialসংরক্ষণ করে না!) সংরক্ষণ করে যা এই ছোট্ট স্নিপেট দ্বারা প্রদর্শিত হতে পারে:1..__truediv__

>>> f1 = 1..__truediv__
>>> f2 = partial(truediv, 1.)

>>> f2(1+2j)  # reciprocal of complex number - works
(0.2-0.4j)
>>> f2('a')   # reciprocal of string should raise an exception
TypeError: unsupported operand type(s) for /: 'float' and 'str'

>>> f1(1+2j)  # reciprocal of complex number - works but gives an unexpected result
NotImplemented
>>> f1('a')   # reciprocal of string should raise an exception but it doesn't
NotImplemented

এর কারণ 1. / (1+2j)এটি দ্বারা float.__truediv__তবে মূল্যায়ন করা হয় না complex.__rtruediv__- operator.truedivএটি নিশ্চিত করে যে স্বাভাবিক অপারেশন ফিরে আসার সময় বিপরীত অপারেশন বলা হয় NotImplementedতবে আপনি যখন __truediv__সরাসরি কাজ করেন তখন আপনার এই ফলব্যাক থাকে না । "প্রত্যাশিত আচরণ" এর এই ক্ষতিটি আপনার (সাধারণত) সরাসরি যাদু পদ্ধতি ব্যবহার না করার মূল কারণ।


40

দুটি বিন্দু একসাথে প্রথমে কিছুটা বিশ্রী হতে পারে:

f = 1..__truediv__ # or 1..__div__ for python 2

তবে এটি লেখার মতোই:

f = 1.0.__truediv__ # or 1.0.__div__ for python 2

কারণ floatআক্ষরিক তিনটি রূপে রচনা করা যেতে পারে:

normal_float = 1.0
short_float = 1.  # == 1.0
prefixed_float = .1  # == 0.1

অবাক করা বিষয়, কেন এই বৈধ সিনট্যাক্স কিন্তু 1.__truediv__তা নয়?
অ্যালেক্স হল

3
@ অ্যালেক্সহল এখানে দেখুন । .সংখ্যা অংশ হিসেবে পার্স করা বলে মনে হয়, এবং তারপর .পদ্ধতি অ্যাকসেসর জন্য অনুপস্থিত।
tobias_k

7
তবে এটি যেহেতু বিশ্রী এবং অস্পষ্ট বাক্য গঠন, সম্ভবত এটি এড়ানো উচিত।
DrMcCleod

11

কী f = 1..__truediv__?

fএকটি মান সহ একটি ভাসা উপর একটি আবদ্ধ বিশেষ পদ্ধতি। বিশেষ করে,

1.0 / x

পাইথন 3-তে,

(1.0).__truediv__(x)

প্রমান:

class Float(float):
    def __truediv__(self, other):
        print('__truediv__ called')
        return super(Float, self).__truediv__(other)

এবং:

>>> one = Float(1)
>>> one/2
__truediv__ called
0.5

আমরা যদি:

f = one.__truediv__

আমরা সেই বাউন্ড পদ্ধতিতে আবদ্ধ একটি নাম ধরে রাখি

>>> f(2)
__truediv__ called
0.5
>>> f(3)
__truediv__ called
0.3333333333333333

যদি আমরা একটি আঁটযুক্ত লুপে সেই বিন্দুযুক্ত চেহারাটি করছিলাম তবে এটি কিছুটা সময় সাশ্রয় করতে পারে।

বিমূর্ত সিনট্যাক্স ট্রি (এএসটি) পার্স করা হচ্ছে

আমরা দেখতে পাচ্ছি যে অভিব্যক্তির জন্য এএসটি পার্সিং করা আমাদেরকে বলে যে আমরা __truediv__ভাসমান পয়েন্ট সংখ্যাতে বৈশিষ্ট্যটি পাচ্ছি 1.0,:

>>> import ast
>>> ast.dump(ast.parse('1..__truediv__').body[0])
"Expr(value=Attribute(value=Num(n=1.0), attr='__truediv__', ctx=Load()))"

আপনি একই ফলস্বরূপ ফাংশনটি থেকে পেতে পারেন:

f = float(1).__truediv__

অথবা

f = (1.0).__truediv__

সিদ্ধান্তগ্রহণ

ছাড়ের মাধ্যমেও আমরা সেখানে যেতে পারি।

আসুন এটি নির্মাণ করুন।

1 নিজেই একটি int:

>>> 1
1
>>> type(1)
<type 'int'>

ভাসমান হওয়ার পরে 1 পিরিয়ড সহ:

>>> 1.
1.0
>>> type(1.)
<type 'float'>

পরবর্তী বিন্দুটি নিজেই সিনট্যাক্স এরর হবে, তবে এটি শুরু হবে ভাসমানের উদাহরণে:

>>> 1..__truediv__
<method-wrapper '__truediv__' of float object at 0x0D1C7BF0>

আর কেউই এই কথা উল্লেখ করেছেন - এটি এখন একটি হল "বাউন্ড পদ্ধতি" , ভাসা উপর 1.0:

>>> f = 1..__truediv__
>>> f
<method-wrapper '__truediv__' of float object at 0x127F3CD8>
>>> f(2)
0.5
>>> f(3)
0.33333333333333331

আমরা একই ফাংশনটি আরও পাঠযোগ্যভাবে সম্পাদন করতে পারি:

>>> def divide_one_by(x):
...     return 1.0/x
...     
>>> divide_one_by(2)
0.5
>>> divide_one_by(3)
0.33333333333333331

কর্মক্ষমতা

divide_one_byফাংশনের খারাপ দিকটি এটির জন্য অন্য একটি পাইথন স্ট্যাক ফ্রেম প্রয়োজন, এটি আবদ্ধ পদ্ধতির চেয়ে কিছুটা ধীর করে তোলে:

>>> def f_1():
...     for x in range(1, 11):
...         f(x)
...         
>>> def f_2():
...     for x in range(1, 11):
...         divide_one_by(x)
...         
>>> timeit.repeat(f_1)
[2.5495760687176485, 2.5585621018805469, 2.5411816588331888]
>>> timeit.repeat(f_2)
[3.479687248616699, 3.46196088706062, 3.473726342237768]

অবশ্যই, আপনি যদি কেবল সাদামাটা আক্ষরিক ব্যবহার করতে পারেন তবে এটি আরও দ্রুত:

>>> def f_3():
...     for x in range(1, 11):
...         1.0/x
...         
>>> timeit.repeat(f_3)
[2.1224895628296281, 2.1219930218637728, 2.1280188256941983]
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.