Julia: وحدة واستيراد التعرج

تم إنشاؤها على ٥ سبتمبر ٢٠١٢  ·  96تعليقات  ·  مصدر: JuliaLang/julia

بالنسبة لنظام الوحدات ، يمكننا استيراد واستخدام وحدة برمز النقطة:

import ArgParse
... 
    ArgParse.add_argument(p, "--opt1") 
...

يمكن أن يكون هذا مفيدًا لمنع تلوث مساحة الاسم. ولكن بسبب الإسهاب في أسماء الوحدات ، سيكون من الجيد أن يكون لديك أسماء مستعارة للوحدة:

import ArgParse as ap 
... 
    ap.add_argument(p, "--opt1") 
...
design modules speculative

التعليق الأكثر فائدة

كانت هذه المشكلة موجودة منذ وقت طويل ، على الرغم من أنه لا يزال يتعين مناقشة بعض الامتدادات ، فإن

import LongPackage as longpkg

نفسها تبدو معقولة جدًا.

ال 96 كومينتر

أدركت منذ دقائق أنه يمكنك القيام بما يلي:

import ArgParse
ap = ArgParse

ap.add_argument(...)

ما زلت أعتقد أنه سيكون من الجيد الحصول على تدوين "الاستيراد كـ" كسكر نحوي بالرغم من ذلك.

بينما أنا هنا وأفكر في الأمر ، سيكون من الجيد أيضًا أن يكون لديك طريقة لاستيراد وظائف محددة متعددة في نفس سطر الاستيراد ، كما هو مذكور في منشور المنتدى JeffreySarnoff . لم يكشف البحث في المشكلات عن مثل هذا الطلب حتى الآن.

شيء مثل

# from the forum post
import Module.(export1,export2,export3)
# or
import Module.[export1,export2,export3]
# or maybe
import Module.{export1,export2,export3}

إنها قضية مختلفة عن هذه ، لكنها ذات صلة. هل علي أن

  1. تحديث هذه المشكلة ، أو
  2. إنشاء عدد جديد

(أفترض أن فائدة مثل هذه الميزة ليست مثيرة للجدل ...)

تحرير : هذا يعمل الآن مع import Module: export1, export2, export3

أعتقد أنه يجب أن يدعم أيضًا على سبيل المثال

import ArgParse.add_argument as addarg

لتتمكن من إعادة تسمية أعضاء الوحدة النمطية عند الاستيراد.

هل تتساءل كيف ستشارك أسماء الوظائف المعاد تسميتها في الإرسال؟

يجب أن تعمل بشكل أساسي مثل الاسم المستعار ، أي ما يعادل const foo = Base.bar .

يجب أن يعمل بشكل أساسي مثل الاسم المستعار ، أي ما يعادل const foo =
Base.bar.

عندما نستورد دالة ، فإننا إما نخطط لاستخدامها أو تجاوزها. منح
ما ورد أعلاه ، مع

استيراد Base.bar كـ foo

يمكننا بالتأكيد استخدام foo كـ Base.bar ، لكن تعريف foo يتجاوز أيضًا
Base.bar؟ ينبغي له؟

هذه مشكلة قديمة ، لكنني أعتقد أن الوقت قد حان لإعادة النظر فيها حيث نقترب من 0.2

في كتابة الأكواد ، وجدت أنني كنت أرغب دائمًا في كتابة import NumericExtensions as ne وانتهى بي الأمر بتذكير نفسي بأن هذا لم يتم دعمه.

أعتقد أن هذا ليس صعب التنفيذ ، وفي رأيي ، هذا أجمل بكثير من الكتابة

import NumericExtensions
const ne = NumericExtensions

+1

+1

هل هذا لا يزال ذا صلة؟ أنا شخصياً لا أمانع فقط القيام بالدولار الإضافي foo = Foo لتسمية الوحدة النمطية ، ولكن يبدو أنه كان هناك بعض الإجماع على دعم الاسم المستعار للسكر. قد يضطر الشخص الذي يشعر بقوة كافية إلى إجراء العلاقات العامة بنفسه.
لاحظ مع ذلك أن x as y كان من أقوى المتنافسين على بناء جملة convert(y,x) المذكور في # 1470. يبدو أنه لن يكون من الصعب للغاية إزالة الغموض عن الاثنين ، ولكن فقط لاحظ.

تكمن قيمة هذه الميزة في أنه يمكنك تجنب استيراد الاسم الأصلي.

+1
سيكون من الرائع الحصول على هذه الميزة.

+1

بدلاً من إدخال كلمة رئيسية جديدة as ، ماذا عن استخدام عامل التشغيل => ، كما في

import Tlahuixcalpantecuhtli => Venus: xxxxxxxxx => x9, yyyyyyyy => y8, zzz

سيسمح هذا بشكل متعامد بالتعرّف على الوحدة النمطية وأي مجموعة فرعية من المتغيرات في نفس الصيغة.

لا أعرف ، هذا يبدو قبيحًا حقًا بالنسبة لي.

import Tlahuixcalpantecuhtli as Venus: xxxxxxxxx as x9, yyyyyyyy as y8, zzz

هل هذا أفضل؟ أجده أقل قابلية للقراءة.

أنا شخصياً أجد أن as أكثر وضوحًا من => ، والذي يبدو أنه قد يعني أي عدد من الأشياء.

الكشف الكامل: تحيز بيثون.

تعجبني بنية => أفضل من بناء الجملة as .

أنا أحب الدراجات التي تتعثر في توازن ناش.

لماذا تعيد ربط الرموز الداخلية للوحدة النمطية؟ إنه قبيح لأنك لا يجب أن تفعل ذلك حقًا.

تعجبني صيغة استيراد هاسكل . أشعر أن مساحات أسماء بايثون أكثر دقة من وحدات جوليا النمطية. تشعر وحدة جوليا بروح أكثر تجاه وحدات هاسكل ، لذلك ربما يجب أن نبحث هناك عن الإلهام.

أتفق مع ssfrr ، فإن الكلمة الرئيسية as أكثر وضوحًا ، وهي مألوفة أيضًا لمستخدمي Python / Haskell. لحل مشكلة StefanKarpinski مع قابلية القراءة ، سيساعد النهج الشبيه ببيثون أيضًا:

from Tlahuixcalpantecuhtli as Venus import xxxxxxxxx as x9, yyyyyyyy as y8, zzz

أشعر أنني أتحدث إلى REPL. لكني أعلم أن هذا النوع من الاقتراحات غير ممكن.

from Tlahuixcalpantecuhtli as Venus import xxxxxxxxx as x9, yyyyyyyy as y8, zzz

هذا هو أحد أقل الخيارات النحوية المفضلة لدي في بايثون. لتغيير المعنى قليلاً ، عليك إعادة ترتيب الخط بالكامل بشكل جذري ، وتغيير الكلمة الأساسية الأولية وترتيب كل شيء. يبدو مختلفًا تمامًا عن الواردات الأخرى ، مما يحجب هذه الحقيقة عن أنهم يفعلون نفس الشيء تقريبًا. هذا تصميم نحوي رهيب ، imo ، يعطي وزنًا كبيرًا جدًا لكونك تشبه اللغة الإنجليزية بشكل سطحي.

: +1: لـ as ،: -1: لـ from

يبدو أن import a => b: c => d, e => f يبدو قليلاً جدًا بالنسبة لي.

لم أسمع قط بتوازن ناش وبعد أن قرأت عنها لا أعتقد أن هذا يشكل واحدًا. لكن الشيء المضحك هو أنه في حين أن هذا الدراج يحتوي على 10 ردود في ساعة واحدة ، إلا أن عرضًا على # 6984 يبدو لي أنه مهم جدًا (ولكنه أكثر صعوبة) قد مضى 4 ساعات بدون تعليق!

بالنسبة إلى as مقابل => : إما سيكون تحسينًا رائعًا للوضع الحالي.

نقطة جيدة @ BobPortmann على # 6984.

أعتقد أن => رائع لهذا ، FWIW.

لكن الشيء المضحك هو أنه في حين أن هذا الدراج يحتوي على 10 ردود في ساعة واحدة ، إلا أن عرضًا على # 6984 يبدو لي أنه مهم جدًا (ولكنه أكثر صعوبة) قد مضى 4 ساعات بدون تعليق!

في القياس الأصلي لمرض باركنسون ، هذه المشكلة هي سقيفة الدراجة ورقم 6984 هو المفاعل النووي.

:)

أكره تحريك هذا القدر ولكني أعتقد أنني أفضل as . => غامض بعض الشيء ، ومن الغريب مشاركة بناء الجملة مع القواميس. ربما يكون الأمر منطقيًا فقط = : import Foo: x = y ، على غرار const x = Foo.y الذي ستفعله الآن.

إذا لم يكن هناك شيء آخر ، فإن هذا الجدول في وثائق هاسكل مفيد حقًا. غالبًا (خاصةً عند تعلم جوليا لأول مرة) مرتبك فيما يتعلق بوقت استخدام import / using / require ، أو متى أفعل import Mod.thing مقابل import Mod: thing . كنت في الواقع أبحث فقط عن تفسير بناء جملة القولون على الواردات ولم أتمكن من العثور عليه.

jakebolewski يبدو أن بناء جملة Haskell قريب جدًا ، حيث تعادل Julia using لـ Haskell (غير مؤهل) import ، و Julia import تعادل import qualified لـ Haskell


كنقطة بداية ، هل يمكن لشخص يعرف أن يؤكد بشكل أفضل أن هذا ملخص جيد للاستيراد / استخدام التركيب المتاح حاليًا؟ لنفترض أن لدينا وحدة Mod تقوم بتصدير الوظائف x و y ، ولديها أيضًا وظائف غير مُصدرة p و q .

import Mod يجلب Mod.x و Mod.y و Mod.p و Mod.q . جميع الوظائف المستوردة متاحة لتمديد الأسلوب

using Mod يجلب x و y و Mod.x و Mod.y و Mod.p و Mod.q . x و y غير متاحين لتمديد الطريقة ، لكن Mod.* متوفران.

import Mod.x, Mod.p يجلب x و p و Mod.x و Mod.y و Mod.p و Mod.q . كلهم متاحون لتمديد الطريقة.

import Mod: x, p هو نفسه import Mod.x, Mod.p

using Mod.x, Mod.p يجلب x و p و Mod.x و Mod.y و Mod.p و Mod.q . x و p غير متوفرين لتمديد الطريقة ولكن Mod.* متوفران.

using Mod: x, p هو نفسه using Mod.x, Mod.p

بقدر ما أستطيع أن أقول إن using Mod هو الاستخدام الوحيد الذي يهتم بما يتم تصديره بواسطة Mod .

سيكون من المفيد حقًا الحصول على هذا الملخص في مستندات الوحدة النمطية! هل يمكن لأي شخص تأكيد ذلك ، حتى أتمكن من إعداد العلاقات العامة؟

يبدو أن الإصدار الأقل إثارة للجدل هو:

import Tlahuixcalpantecuhtli as Venus: xxxxxxxxx as x9, yyyyyyyy as y8, zzz

أنا رائع مع ذلك. على الرغم من ذلك ، فإن إصدار المهمة مثير للاهتمام ، حيث يتم اختباره:

import Venus = Tlahuixcalpantecuhtli: x9 = xxxxxxxxx, y8 = yyyyyyyy, zzz

اعتقدت أنني سأكره ذلك ، لكنه في الواقع لطيف جدًا. يعجبني أن الأسماء التي يتم تقديمها في هذه الوحدة تأتي أولاً وأبرزها - وهذا هو الشيء الأكثر أهمية من نواح كثيرة.

jakebolewski : لماذا تعيد ربط الرموز الداخلية للوحدة النمطية؟ إنه قبيح لأنك لا يجب أن تفعل ذلك حقًا.

قد ترغب في استيراد روابط بأسماء متضاربة من وحدتين مختلفتين وهذا يسمح بذلك. يمكنك أيضًا تأهيلهم بشكل كامل ، ولكن إذا كنا ندعم التسمية المستعارة ، فقد ندعم هذا أيضًا.

بعض الأسطر الجديدة الموضوعة بشكل جيد تجعل إما قراءة أكثر سهولة ، IMO:

import Tlahuixcalpantecuhtli as Venus:
    xxxxxxxxx as x9, 
    yyyyyyyy as y8,
    zzz

أو

import Venus = Tlahuixcalpantecuhtli: 
    x9 = xxxxxxxxx, 
    y8 = yyyyyyyy, 
    zzz

أجد أنني أفضل إصدار المهمة بشدة. الاستيراد هو شكل من أشكال التنازل ، بعد كل شيء.

سيكون من المفيد حقًا الحصول على هذا الملخص في مستندات الوحدة النمطية! هل يمكن لأي شخص تأكيد ذلك ، حتى أتمكن من إعداد العلاقات العامة؟

@ brk00 ، اذهب لذلك!

kmsquire ، سأعمل عليها اليوم!

لكن قبل القيام بذلك ، أريد التأكد من أنني أفهمها جيدًا. في مثال ssfrr ، افترض أنني أستخدم REPL واكتب using Mod . الدالات المستوردة x و y غير متوفرة لتمديد الطريقة. هذا يعني أنه إذا قمت بالإعلان عن دالتين x و y أخريين ، فلن يكون بإمكاني الوصول إلى طرق Mod التي قمت باستيرادها مرة واحدة ، فقط للوظائف الجديدة؟

هذا ما يحدث إذا حاولت توسيع دالة دون استيرادها:

julia> module Mod

       export x, y

       x() = "x"
       y() = "y"
       p() = "p"
       q() = "q"

       end

julia> using Mod

julia> x()
"x"

julia> p()
ERROR: p not defined

julia> x(n) = n
ERROR: error in method definition: function Mod.x must be explicitly imported to be extended

يمكنك إضافة طريقة مثل:

julia> import Mod: x # or import Mod.x

julia> x(n) = n
x (generic function with 2 methods)

julia> methods(x)
# 2 methods for generic function "x":
x() at none:5
x(n) at none:1

حسنًا ، لقد كنت مرتبكًا من سلوك حل الاسم:

julia> module Mod

       export x, y

       x() = "x"
       y() = "y"
       p() = "p"
       q() = "q"

       end

julia> using Mod

julia> x(n) = n
x (generic function with 1 method)

إذا قمت بتعيين وظيفة جديدة إلى x قبل _ using_ الوظيفة التي قمت باستيرادها للتو باستخدام using Mod ، فلن يظهر الخطأ. لكن إذا قمت ، على سبيل المثال ، بالاتصال بـ x() قبل التعيين الجديد (كما فعلت في مثالك) ، فسيتم رفع الخطأ بالفعل.

آه ، ممتع! لم أكن أعرف عن ذلك. صادف أن اتصلت بـ x لتوضيح مسافة الاسم بعد using .

ربما يمكن لأحد المطورين الأساسيين إلقاء بعض الضوء. ماذا يحدث عندما يتم استدعاء x والذي يتسبب في حدوث الخطأ عند محاولة التحميل الزائد؟

أجد أن الاسم المستعار الذي اقترحه carlobaldassi أعلاه مفيد جدًا في الممارسة.

أتساءل عما إذا كان بإمكان import إرجاع كائن الوحدة النمطية ، بحيث يمكن تسميته مباشرة مع مهمة ، مع أو بدون const ؟ على سبيل المثال

const Shortname = import ModuleWithLongName

بدلا من

import ModuleWithLongName
const Shortname = ModuleWithLongName

لن يتطلب هذا أي بناء جملة جديد ، فقط مجموعة من عناصر بناء الجملة الموجودة. أدرك أن حاليًا import عبارة عن "بيان" يُدعى فقط للتأثيرات الجانبية وليس له قيمة. إذا كان المحلل اللغوي لا يسمح بذلك ، فأنا أفضل import("Module") أو شيء مشابه.

أعتقد أن خيار وحدات الاسم المستعار قد يكون لطيفًا ، لكنني أعتقد أيضًا أن هناك جانبًا سلبيًا لم يذكره أحد: يمكن أن يحجب الشفرة بشكل كبير. من منظور قارئ الكود ، من الجيد أن يكون لديك اسم وصفي واحد فقط لوحدة نمطية.

تافهة جدا للبحث عن بالرغم من ذلك؟ من المحتمل أيضًا أن تكون النماذج المختصرة موحدة للحزم الشائعة مثل np لـ numpy .

ما زلت أفضل numpy على np وحتى Arrays على numpy . يبدو numpy وكأنه تقاطع بين حركة رقص في خمسينيات القرن الماضي وطاعون مميت.

يمكن بسهولة كتابة:

Base.require("ArgParse")
const ap = Main.ArgParse

هذا لا يحتاج إلى بناء جملة لـ 1.0

أشعر أنه يجب أن يكون لدينا بناء جملة لهذا. نعم ، يمكننا العيش بدونها حيث يمكنك القيام بمهمة require و const ، لكن استخدام require أمر قبيح للغاية وعدم وجود بناء مناسب يثني الناس عن إعادة تسمية الأشياء كما يريدون / يحتاجون إليه.

إن خدعة const سهلة تكون قصيرة عندما يحتاج المرء إلى تسمية ماكرو مستعارة ، هذه هي الطريقة التي أفعل بها ذلك ، وقد استغرق الأمر بعض الوقت لمعرفة:

julia> macro foo(a, b, c)                                  
           a, b, c                                         
       end                                                 
<strong i="8">@foo</strong> (macro with 1 method)                                 

julia> macro f(args...)                                    
           Expr(:macrocall, Symbol("@foo"), args...) |> esc
       end                                                 
<strong i="9">@f</strong> (macro with 1 method)                                   

julia> <strong i="10">@f</strong> 1 2 3                                            
(1,2,3)                                                    

في ImportMacros.jl أقوم بتنفيذ ما يلي:

  • <strong i="15">@from</strong> Foo.Bar use foo as f
  • <strong i="18">@from</strong> Foo.Bar use <strong i="19">@foo</strong> as @f

انظر: https://github.com/fredrikekre/ImportMacros.jl/pull/3

@ Ismael-VC

يحاول

<strong i="7">@eval</strong> const $(Symbol("@foo")) = $(Symbol("@bar"))

وهو أقبح ولكنه أقصر وربما أكثر وضوحًا من تحديد ماكرو محليًا

TotalVerb شكرا مرة أخرى لمساعدتكم!

يبدو أن الوظيفة الوحيدة المفقودة من Julia + ImportMacros هي الاسم المستعار لكل من الوحدة النمطية ومزيج من تسمية عدد متغير من الكائنات من هذه الوحدة النمطية واستيراد عناصر أخرى بدون اسم مستعار:

  • <strong i="9">@from</strong> Foo.Bar as B use foo as f, <strong i="10">@bar</strong> as <strong i="11">@b</strong>, baz

أو بدون from :

  • import Foo.Bar as B: foo as f, <strong i="17">@bar</strong> as <strong i="18">@b</strong>, baz
  • import B = Foo.Bar: f = foo, <strong i="21">@b</strong> = <strong i="22">@bar</strong>, baz

يبدو أن الأخير غير ممكن مع وحدات الماكرو:

julia> parse("<strong i="26">@from</strong> Foo.Bar as B use foo as f, <strong i="27">@bar</strong> as <strong i="28">@b</strong>, baz")
:(<strong i="29">@from</strong> Foo.Bar as B use foo as (f,@bar(as,(@b(),baz))))

julia> parse("<strong i="30">@import</strong> Foo.Bar as B: foo as f, <strong i="31">@bar</strong> as <strong i="32">@b</strong>, baz")
:(<strong i="33">@import</strong> Foo.Bar as B:foo as (f,@bar(as,(@b(),baz))))

julia> parse("<strong i="34">@import</strong> B = Foo.Bar: f = foo, <strong i="35">@b</strong> = <strong i="36">@bar</strong>, baz")
ERROR: ParseError("unexpected \"=\"")
 in #parse#310(::Bool, ::Bool, ::Function, ::String, ::Int64) at .\parse.jl:184
 in (::Base.#kw##parse)(::Array{Any,1}, ::Base.#parse, ::String, ::Int64) at .\<missing>:0
 in #parse#311(::Bool, ::Function, ::String) at .\parse.jl:194
 in parse(::String) at .\parse.jl:194

هذا لا يحتاج في الواقع إلى تقرير 1.0 لأن جميع الصيغ المقترحة هي إما أخطاء أو هراء تام.

ما الذي يجب أن يحدث للاسم المستعار للوحدة النمطية عند إعادة تعريف الوحدة الأصلية ، على سبيل المثال ، بواسطة reload("...") على REPL؟ باستخدام نهج const M = MyModule ، لا يزال M يشير إلى الوحدة النمطية القديمة بعد إعادة التحميل ، لذا فإن أي أسماء تم تحديدها حديثًا في MyModule يمكن الوصول إليها فقط بواسطة MyModule.name لكن ليس M.name .

في هذه الحالة ، يجب أن يكون بناء جملة الاسم المستعار أكثر من مجرد سكر نحوي مقابل const M = Module ، ولكن بدلاً من ذلك تأكد من أن M يشير دائمًا إلى نفس الشيء مثل MyModule .

سيؤدي هذا أيضًا إلى تبسيط سير عمل REPL حيث يمكنني الاستمرار في import وحدة نمطية أثناء التطوير ولكن يمكنني الرجوع إليها عبر اسم مستعار أقصر دون الحاجة إلى إعادة إنشاء اسم مستعار (ليس const ) في كل مرة reload .

اعتبارًا من الآن ، تمت إزالة reload لذا لم يعد هذا القلق قابلاً للتطبيق.

ينطبق هذا أيضًا على include ، أم أنني أفتقد شيئًا ما؟ بشكل عام ، عند إعادة تعريف الوحدة النمطية ، يشير اسم الوحدة النمطية import ed إلى التعريف الجديد بينما يشير الاسم المستعار المحدد بواسطة التعيين إلى التعريف القديم ، أليس كذلك؟

لا يجب ألا يكون هذا مصدر قلق. لن يتم تغيير الاسم الذي تم استيراده مطلقًا عند إعادة تعريف الوحدة النمطية ، بما في ذلك الاسم العادي import . ما تغير هو الوحدة النمطية التي سيتم استيرادها إذا قمت باستيرادها مرة أخرى. لطالما كان الاستيراد مجرد ربط.

حسنًا ، ربما لم أقم بالتعبير عن نفسي بوضوح ، فإليك مثال: إذا قمت بإنشاء ملف test.jl بالمحتوى

module Tst
f() = 1
end

يمكنك تحميله واستيراد Tst وتحديد الاسم المستعار لـ Tst وكل شيء على ما يرام:

julia> include("test.jl")
Tst

julia> import Tst

julia> const Tst2 = Tst
Tst

julia> Tst.f()
1

julia> Tst2.f()
1

إذا قمت الآن بتغيير test.jl إلى

module Tst
f() = 2
end

وإعادة- include في REPL ، تتصرف الوحدة النمطية والاسم المستعار الخاص بها بشكل مختلف:

julia> include("test.jl")
WARNING: replacing module Tst
Tst

julia> Tst.f()
2

julia> Tst2.f()
1

أرى سبب حدوث ذلك ، لكنني أعتقد أن هذا لا يجب أن يحدث عند إنشاء اسم مستعار بشيء مثل import Tst as Tst2 .

لقد اختبرت هذا على 0.6.2 ، وفي الوقت الحالي لا يمكنني اختباره على 0.7 ، لذلك لا يمكنني اختباره الآن إذا كان هذا هو الحال.

أنت لا تستورده على الإطلاق. الوحدة النمطية التي تقوم بتضمينها محددة بالفعل في نطاقك. import غير متوفر.

صحيح ، لكن ليس هذا هو الهدف. النقطة المهمة هي ما يحدث عندما أفعل شيئًا مثل import Tst as Tst2 الافتراضي. إذن هذه العبارة ليست no-op ولكنها تنشئ اسمًا مستعارًا.

إذا كان هذا الاسم المستعار يعمل مثل const Tst2 = Tst ، فإن إعادة تعريف الوحدة Tst ستجعل الاسم المستعار يشير إلى الإصدار القديم من الوحدة. هذا غير مرغوب فيه بأي حال من الأحوال. يجب أن يشير الاسم المستعار إلى الإصدار الجديد من Tst أيضًا ، أو يجب إجبار المستخدم على إعادة إنشاء الاسم المستعار. ولكن في الحالة الأخيرة ، يجب أن يؤدي استخدام الاسم المستعار القديم دون إعادة إنشائه إلى حدوث خطأ بدلاً من الإشارة إلى الوحدة النمطية القديمة.

هذا هو الهدف تماما. تتعلق هذه المشكلة بإضافة دالة إلى import وليس إلى تعريف الوحدة النمطية. import الخاص بك غير متوفر وبعد إزالته لم يعد الرمز الخاص بك يحتوي على أي import أو using لذا فهو غير مرتبط بهذه المشكلة. يرجى تغييره بحيث لا يتم تعريف الوحدة في نفس النطاق مثل import .

سيعمل import Tst as Tst2 بنفس الطريقة التي يعمل بها import Tst من حيث ما هو ملزم بهذا الاسم ، والذي يكون دائمًا ملزمًا وليس أي شيء سحري تريده. لا يتعلق هذا بإضافة اسم مستعار عند تحديد الوحدة.

بعبارة أخرى ، فأنت تقوم بالتشفير بشكل أساسي ،

a = Ref(1) # include
a = a # import
b = a # alias
a = Ref(2) # include again

وليس من المنطقي الشكوى من سلوك b = a لأن a لا يرتبط بـ a = a على الإطلاق. كل ما تراه هو التأثير الجانبي لتعريف الوحدة في نفس النطاق مثل الاستيراد (على سبيل المثال ، a = a و a = Ref(...) في نفس النطاق) في مثال سيء.

حسنًا ، أردت فقط أن أشير إلى أنه في بعض الحالات ، لن يعمل الاسم المستعار المحدد بواسطة مهمة كما هو متوقع. ربما اخترت مثالا سيئا. اعتقدت أن هذا قد يكون مهمًا لبناء الجملة الذي ينشئ اسمًا مستعارًا للوحدة (سواء أكان مرتبطًا بـ import أم لا) ، لكن هذا افتراضي الآن على أي حال. آسف على الضوضاء.

كانت هذه المشكلة موجودة منذ وقت طويل ، على الرغم من أنه لا يزال يتعين مناقشة بعض الامتدادات ، فإن

import LongPackage as longpkg

نفسها تبدو معقولة جدًا.

صدم. أتساءل ما هو أفضل حل - في الوقت الحالي - يبدو؟ هذا ما أفعله:

import LinearAlgebra
const linalg = LinearAlgebra

الرجاء تصحيح لي إذا كان هناك حل أفضل!

هذا هو المعيار الحالي.

ماذا عن ~ بناء الجملة؟ لا أعرف التداعيات ، لكن لها جمالية جميلة. أيضًا ، يتم استخدام ~ كرمز تقريبي.

import LongPackage ~ lp

تضمين التغريدة

تضمين التغريدة

هذا هو أحد أقل الخيارات النحوية المفضلة لدي في بايثون. لتغيير المعنى قليلاً ، عليك إعادة ترتيب الخط بالكامل بشكل جذري ، وتغيير الكلمة الأساسية الأولية وترتيب كل شيء. يبدو مختلفًا تمامًا عن الواردات الأخرى ، مما يحجب هذه الحقيقة عن أنهم يفعلون نفس الشيء تقريبًا. هذا تصميم نحوي رهيب ، imo ، يعطي وزنًا كبيرًا جدًا لكونك تشبه اللغة الإنجليزية بشكل سطحي.

في هذه الحالة ، ~ لن يكون له علاقة بالجانب الشبيه بالإنجليزية في بناء جملة بايثون. أعتقد أنه عندما أرى ~ ، أدرك فقط المفهوم الرياضي للتقريب. 10.001 ~ 10.

لذا ، بهذا المعنى ، أجد ~ لطيفًا جدًا في الواقع.

import LongPackage ~ lp
import HugePackage ~ hp
import MassivePackage ~ mp
import GiantPackage ~ gp

:-)

حسنًا - انسى لغة python - أحذف هذا التعليق لصالح

lp imports LongPlayingRecords
hp imports HewlettPackard
mp imports MilitaryPolice
gp imports PariForNumberTheory

لم يعجبني في الأصل ولكن يبدو أن الكثير من الناس يرغبون بطبيعة الحال في كتابة هذا بـ as يجب أن أقول أنه يبدو من المنحرف فعل أي شيء آخر. ليس من الضروري أن تكون محجوزة ككلمة رئيسية أو أي شيء لأن هذا سياق نحوي واضح.

لغة برمجة تحاول أن تعرف الناس ما تعنيه!؟!

تضمين التغريدة

لغة برمجة تحاول أن تكون أفضل من بايثون !!!

neilpanchal Julia هي بالتأكيد لغة تحاول أن تكون أفضل من Python من نواحٍ عديدة. من ناحية أخرى ، من الواضح أنها لا تخرج عن طريقتها لتكون مختلفًا عن بايثون حيث حصلت بايثون على شيء صحيح. تستعير جوليا الاصطلاحات النحوية من بايثون من اليسار واليمين.

الرجاء استخدام python as . لقد فهموها بشكل صحيح.

julia> استيراد LightGraphs كـ lg
خطأ: بناء الجملة: رمز إضافي "كـ" بعد نهاية التعبير

مجرد تعليق آخر بقيمة 0.02 دولار لصالح as الذي يبتعد عن Python. fwiw ، الآن بعد أن أستخدم Julia مع بعض الانتظام مرة أخرى ، أفتقد هذا. ليس كما هو الحال في Python ، ولكن كما هو الحال في Clojure (انظر المثال ) ، حيث يمكن تبسيط مساحات أسماء النطاقات ذات النطاق الحزم (والتي تعد مفيدة للتوضيح) لجعل الاستخدام الصريح للمكتبات أكثر استخدامًا. نظرًا لأن لدي تفضيلًا لتجنب using (أي استيراد أحرف البدل) وجود بعض السكر النحوي إلى import Gadlfy as gf بدون إضافة السطر const gf = (ما أفعله حاليًا) كن في متناول اليد.

تعليق آخر يدعم بناء الجملة as : القلب: أتمنى أن يكون الأمر صعبًا حقًا لإصدارات Julia المستقبلية.

أنا أيضا أتمنى أن يحدث هذا. خاصة أنه ليس تغييرًا كسرًا (أليس كذلك؟).

أعتقد أنه سيتم تنفيذ هذا في مرحلة ما (سأحاول بنفسي إذا كان بإمكاني تخصيص الوقت) ، ولكن في غضون ذلك ، تحتوي الحزمة ImportMacros على جميع الوظائف المطلوبة إلى حد كبير هنا (على الرغم من أنها تفتقر إلى الوثائق) :

<strong i="8">@import</strong> ModuleA as ma
<strong i="9">@using</strong> ModuleB as mb
<strong i="10">@from</strong> ModuleC use long_function_name as func
<strong i="11">@from</strong> Module use <strong i="12">@macroname</strong> as <strong i="13">@alias</strong>

لم أكن أعرف شيئًا عن ImportMacros .jl ، شكرًا للإشارة إلى ذلك. إذا كانت هذه الوظيفة موجودة في حزمة ، فأعتقد أنه ليس من المهم جدًا أن تكون متوفرة باللغة الأساسية.

ما زلت أعتقد أن هذا سيكون جيدًا في اللغة.

الواردات هي IMO بالضبط نوع الشيء الذي تريد دائمًا _ دائمًا _ الرجوع إلى اصطلاحات اللغة الأساسية وليس الالتفاف في وحدات الماكرو أو إضافة تبعية الحزمة. import ... const أفضل شيء يمكن الرجوع إليه ، حتى (على وجه الخصوص) إذا لم يتم تمديد اللغة الأساسية لجعل هذه العملية المكونة من خطوتين أكثر إيجازًا.

على وجه الخصوص ، من القبيح بعض الشيء أن نرى

using ImportMacros
<strong i="6">@using</strong> OtherPackage as ...
<strong i="7">@using</strong> ThirdPackage as ...

لأن using غير الماكرو يبقى ثابتًا.

ماذا عن إعادة import للوحدة / الوظيفة / كل ما تجلبه بالفعل إلى النطاق؟
ثم يمكنك الكتابة
lg = import LightGraphs
baz = import foo.bar
baz, kit, kat = import foo : bar1, bar2, bar3
الشيء الوحيد الذي يجب تغييره هو وظيفة الاستيراد

أحب حقًا حل DhruvaSambrani لأنه يتناسب مع نهج جوليا الشامل "كل شيء هو تعبير".

الشيء الوحيد هو أنه من أجل أن يكون متسقًا ، لا يزال يتعين على تعبير الاستيراد تشكيل التأثير الجانبي لإدخال الاسم الكامل في النطاق (ربما لا يمثل كارثة). يمكن أيضًا أن يكون مغلفًا بشكل خاص لعدم استيراد الاسم الكامل ، لكن الغلاف الخاص يكون إجماليًا.

في OCaml (اللغة التي تحتوي على أفضل الوحدات النمطية!) ، يمكنك القيام بشيء مثل:

module LG = LightGraphs

الاختلاف المهم هنا هو أن الاسم المؤهل لكل وحدة يتم تجميعها باستخدام برنامج OCaml يكون تلقائيًا في النطاق.

بالطبع ، فإن استخدام import LightGraphs as LG له ميزة أن "الجميع" يعرفها بالفعل من Python ، لكن ذوقي الشخصي هو أنه من الأفضل إعادة استخدام صيغة المهمة لشيء هو واجب حرفيًا.

أو قد يكون التغيير الأكثر شمولاً هو تقديم "مساحة الاسم" كنوع (إذا تم ذلك بالفعل). ثم import يمكنه توسيع الوحدة / أي شيء في مساحة الاسم وإرجاع مساحة الاسم. ولكن هذا سيؤدي إلى كسر جميع أكواد جوليا لأن إجراء import mod_name لن يجعل مساحة الاسم mod_name متاحة في النطاق العالمي. إذا كان بإمكان المرء بطريقة ما إتاحة مساحة الاسم mod_name للعموم عند استخدام الاستيراد دون تعيين يسبقه ، فهذه ليست مشكلة.

أو قم فقط بإضافة وظيفة جديدة import_as_ns(mod_name) :: Namespace والتي ستكون وظيفة خالصة تقوم بإرجاع جميع الوظائف / الوحدات وما إلى ذلك في مساحة اسم واحدة.

يتناسب مع نهج جوليا الشامل "كل شيء هو تعبير"

ومع ذلك ، فإن import و using خاصان لأنهما يُستخدمان فقط لآثارهما الجانبية ، وفقط في المستوى الأعلى.

بالمناسبة ، نظرًا لأن هذه المشكلة كانت مفتوحة لفترة طويلة ، أتساءل عما إذا كان الفرز على استعداد لإعادة النظر فيه واتخاذ قرار. أود أن أدعو إلى الإغلاق ، منذ ذلك الحين

  1. يوفر import Foo; const Bar = Foo حلاً مثاليًا عندما لا يمانع المستخدم Foo في مساحة الاسم ،
  2. يجب أن يتعامل ImportMacros.jl مع الباقي ،
  3. لا يبدو أنه يتم استخدام أي منهما بشكل متكرر في التعليمات البرمجية العملية لضمان بناء جملة خاص.

سأقول أنه بعد كل هذا الوقت ، ما زلت أفتقد هذا (وأنا أيضًا أستخدم ImportMacros في الكود الخاص بي).

أعتقد أن أسلوب القهوة الذي تكتبه يؤثر على الحاجة (أو الرغبة) لذلك. عندما أكتب ML أو الكود العلمي ، أجد أنني لا أفوتها كثيرًا. عندما أكتب كودًا آخر يستخدم عددًا من الحزم ذات الأسماء الطويلة ، أجد أنني أستخدم إيمبورتماكروس أكثر من غيرها.

ImportMacros كافٍ. أنا فقط أتفق مع التعليقات التي تقول إنها لا تبدو نظيفة.

أنا أتطلع أيضًا إلى اليوم الذي يمكنني فيه استخدام منسق تلقائي في المحرر الخاص بي لفرز وارداتي ... ولكن من غير المرجح أن تعرف ما يجب فعله باستخدام @using ...

أتفق أيضًا مع kmsquire على أن هذه ليست مشكلة كبيرة ، ويجب أن يكون ImportMacros كافيًا. لكن مهما كانت الطريقة التي يجب توثيقها حتى لا تظهر مرة أخرى.

على الرغم من أنني ما زلت أحب السكر m=import Module

لم أكن أنوي أن تشير رسالتي إلى أن هذه ليست مشكلة كبيرة.

ما زلت أفضل بناء الجملة لهذا.

ImportMacros كافٍ. أنا فقط أتفق مع التعليقات التي تقول إنها لا تبدو نظيفة.

أنا موافق. أيضًا من أجل:

using ImportMacros
<strong i="8">@using</strong> OtherPackage as ...

يجعل الأمر مزعجًا بعض الشيء عند تقديم اللغة للقادمين الجدد أو المبتدئين في البرمجة لشرح سبب بدء نص معين بهذا التناقض ، لأنه يعقد التدفق ويغير تركيز التدريس.

لا يبدو أنه يتم استخدام أي منهما بشكل متكرر في التعليمات البرمجية العملية لضمان بناء جملة خاص

قد يرجع السبب وراء عدم استخدام الأشخاص لـ ImportMacros كثيرًا في التعليمات البرمجية الفعلية إلى المقايضة. على سبيل المثال ، سأستخدم import ... as ... في كل مرة تقريبًا ، ولكن ليس على الأرجح على حساب الاضطرار إلى استيراد حزمة أخرى أولاً للقيام بذلك. أكثر من مجرد تبعية إضافية ، لها أيضًا تأثير من حيث "الإحساس" (ويحب بعض الأشخاص أن تبدو الشفرة الخاصة بهم أنيقة (خاصة في Python أو Julia) 🤷‍♂️ ، وهذا using/@using يعطي بدلاً من ذلك " فيبي "لإدخال نص برمجي).

حسنًا ، "ImportMacros كافٍ". للأشخاص الذين يريدون حقًا استخدامه. لكن هذا هو الشيء ، إنها ليست قضية حيوية ، ويمكن للناس العمل بدونها. ومع ذلك ، أعتقد بشدة أن هذه الأشياء الصغيرة هي التي تجعل بناء جملة اللغة ثابتًا ، ومن ثم يضيف هذا الخيط الوحشي دعمه للقاعدة.

أعتقد أن import ... as ... عبارة عن سكر نحوي يستحق ذلك بالتأكيد ، فمن السهل حقًا فهمه وشرحه ، ومفيد بشكل خاص في لغات مثل Julia حيث تميل الحزمة إلى أن يكون لها أسماء طويلة إلى حد ما (من الواضح ، هذا مهم فقط في ظل افتراض أن الناس لا يريدون أن يفعلوا using ... ).

وحقيقة أن بايثون قد طبقتها أولاً لا ينبغي أن تكون ذات صلة ؛ يجب أن تسعى جوليا جاهدة للحصول على أفضل بناء جملة قبل محاولة إبعاد نفسها عن اللغات الأخرى و / أو التأكيد على هويتها الخاصة.

إن وجود بناء جملة لهذا والاتفاقيات حول الوحدات النمطية الشائعة (أفكر في كيف أنه دائمًا import numpy as np و import matplotlib.pyplot as plt ) من شأنه أيضًا أن يعطي بديلاً موجزًا ​​لعمل using SuchAndSuch والاعتماد على export ed الأسماء (وهو شيء كنت أتجنبه عمومًا في كود "المكتبة").

DominiqueMakowski :

تقديم اللغة للقادمين الجدد أو المبتدئين في البرمجة لشرح سبب بدء نص معين بهذا التناقض

لا أفهم سبب اعتقادك أنه عدم تناسق ، إنه ببساطة إدارة مساحة الاسم ، والتي تعد جزءًا طبيعيًا من البرمجة بشكل عام.

أيضًا ، قد لا تكون إعادة تسمية الوحدات النمطية شيئًا سيواجهه القادمون الجدد إلى جوليا أولاً.

أنا لا أقول أنه لا توجد حالة استخدام ، ولكن قد يكون من النادر تبرير الكلمة الرئيسية الخاصة بها. في الوقت الحالي ، البحث عن using ImportMacros يعطي <10 نتائج فريدة على Github.

سأستخدم الاستيراد ... كـ ... تقريبًا في كل مرة ، ولكن من المحتمل ألا يكون ذلك على حساب الاضطرار إلى استيراد حزمة أخرى أولاً للقيام بذلك

هذا يقطع كلا الاتجاهين: إذا كانت التكلفة (البسيطة جدًا) لاستخدام حزمة ligthweight مثل ImportMacros أو رمز إضافي ( import LongFoo; const Foo = LongFoo ) لا تستحق المنفعة ، فقد لا تكون الفائدة بهذا الحجم .

يجب أن تسعى جوليا جاهدة للحصول على أفضل بناء جملة قبل محاولة إبعاد نفسها عن اللغات الأخرى و / أو التأكيد على هويتها الخاصة.

لست متأكدًا من سبب اعتقادك أن هذا هو الدافع في هذه المناقشة.

هناك بعض الحالات التي قد ترغب فيها في استخدام as حيث لا يعمل التعيين const تمامًا:

julia> using Distributed

julia> import Future; const future = Future
Future

julia> Future === Distributed.Future # oops, this is what we wanted
false

julia> Future === future # not what we wanted `Future` to mean
true

نعم ، يمكنك التغلب على هذا ، لكنه محرج. نظرًا لأنه غالبًا ما يكون مفيدًا ، ومطلوبًا في بعض الأحيان وأن import FooBar as FB هو الصيغة المتفق عليها بشكل عام "الأقل إثارة للدهشة" ، يبدو أن هذا هو ما يجب أن نتبعه. كل هذا يحتاجه شخص ما لجعل العلاقات العامة تنفذه.

مستخدم جديد لـ Julia هنا.
لقد جئت من خلفية R في الغالب ، باستخدام Python أيضًا. لدي تجارب سيئة مع مساحة الاسم الشائع للحزمة التي تؤدي إليها آليات التحميل مثل using . خطر الاصطدام واحد ، ولكن فقط من منظور قابلية القراءة ، فإنهم يمثلون عبئًا عقليًا للتفكير المستمر في وحدة كل طريقة.

لا أعرف مدى تعقيد إضافة بناء الجملة هذا؟ هل هو ممكن للمبتدئ؟

ربما ليس من السهل جدا. سيشمل ذلك اختراق كود المحلل اللغوي المكتوب في المخطط وتوصيل التغيير من خلال AST ، ومن المحتمل أن يلامس بعض كود C أيضًا.

ستكون ميزة رائعة لتجنب تعارض اسم الوظيفة في وحدات متعددة.

من مناقشة على Slack ، أضفت بعض الأفكار

أتساءل عما إذا كان هذا سيجعل الأشخاص أقل حرصًا في اختيار أسماء الوظائف وإضافة طرق بشكل صحيح إلى الوظائف الصحيحة. حقيقة أن ، على سبيل المثال ،

numpy.sin
sympy.sin

وظائف مختلفة هي طريقة مؤكدة لضرورة تنفيذ نسختين من وظيفتك إذا كنت تريد أن تعمل لكل من المدخلات العددية والرمزية. إذا انتشر هذا النوع من المسافات في جوليا أيضًا بسبب الراحة ، فقد يفوتنا الكثير من إعادة استخدام الكود؟ أي ، أخشى أن هذا قد يقلل من " هذا يشجع الناس على العمل معًا " كما صاغته ليندون في https://www.oxinabox.net/2020/02/09/whycompositionaljulia.html

baggepinnen لا أعتقد أن هذا يغير أي شيء في هذا الصدد.

في Julia لا يتم دمج الطرق التي تم تنفيذها في وحدات نمطية مختلفة عن طريق استيراد كلا التابعين إلى نفس مساحة الاسم.

julia> module Foo
           export sin
           sin(s::String) = uppercase(s)
       end
Main.Foo

julia> sin(1)
0.8414709848078965

julia> using .Foo
WARNING: using Foo.sin in module Main conflicts with an existing identifier.

julia> sin("wat")
ERROR: MethodError: no method matching sin(::String)
Closest candidates are:
  sin(::BigFloat) at mpfr.jl:727
  sin(::Missing) at math.jl:1197
  sin(::Complex{Float16}) at math.jl:1145
  ...
Stacktrace:
 [1] top-level scope at REPL[4]:1
 [2] run_repl(::REPL.AbstractREPL, ::Any) at /build/julia/src/julia-1.5.1/usr/share/julia/stdlib/v1.5/REPL/src/REPL.jl:288

julia> Foo.sin("wat")
"WAT"

يتعين على المرء أن يضيف صراحةً إرسالية إلى الوظيفة الأصلية لكي يعمل هذا:

julia> Base.sin(s::String) = Foo.sin(s)

julia> sin("wat")
"WAT"

بقدر ما أستطيع أن أقول ، لا توجد طريقة ممكنة لتسمية الوحدة النمطية لتغيير كيفية إرسال الوظائف.

وبصراحة ، فإن بعض الوظائف التي تحمل الاسم نفسه _يجب_ أن تعيش في مساحات أسماء منفصلة. ستقوم وظيفة find_delta في مكتبة رقمية بعمل شيء لا علاقة له بـ find_delta في مكتبة فرق الملفات. بمجرد أن تصبح شفرتك متعددة الأشكال لدرجة أنها ستجد طريقة للتنفيذ عند المدخلات المعطلة ، فإنك تدخل منطقة JavaScript ، ولا أحد يريد ذلك.

ninjaaron ربما أخفق في نقل بعض الفروق الدقيقة في قلقي أعلاه. لست مهتمًا بتغيير هذا التغيير لأي شيء بخلاف الاستراتيجية التي يختار الأشخاص اتباعها عند تنفيذ المكتبات.
الشخص الذي يقوم بتنفيذ Foo يواجه تحذيرًا مثل

julia> using .Foo
WARNING: using Foo.sin in module Main conflicts with an existing identifier.

يمكنك اختيار إما import .Foo.sin as sin2 ببساطة ، أو التفكير فيما إذا كان يريد حقًا تقديم دفعة جديدة مقابل Base.sin . كانت وجهة نظري أنه إذا أصبح من السهل جدًا اعتبارها وظائف مختلفة ، فربما ينتشر هذا الأمر على نطاق واسع ، حتى في المواقف التي يجب أن تكون فيها طرقًا مختلفة لنفس الوظيفة. الوضع الحالي ، حيث يكون التعامل مع وظائف مختلفة بنفس الاسم أمرًا محرجًا إلى حد ما ، له تأثير جانبي لطيف حيث يتحدث الناس مع بعضهم البعض ويبذلون قصارى جهدهم لمعرفة ما إذا كانت هذه الوظيفة هي نفسها بالفعل أم لا. أنا لا أجادل ضد إمكانية وجود وظائف مختلفة بنفس الاسم ، والتي بالطبع يمكن أن تكون مفيدة للغاية. لست متأكدًا حتى مما إذا كان قلقي مهمًا أم لا ، لكنني اعتقدت أن الأمر يستحق رفعه للتأكد من أنه قد تم النظر فيه.

baggepinnen هذا منطقي ، ولا ضرر من طرحه. لا أعتقد أن هذا سيحدث فرقًا كبيرًا للأشخاص الذين ينشئون مكتبات ، نظرًا لأن الاسم المستعار للوحدة سيؤثر فقط على مستخدمي المكتبة. أعتقد أنه من الممكن أن يؤدي الحصول على تسمية مستعارة أسهل للوحدة النمطية إلى عدد أقل من المستخدمين _ يتساءلون_ حول تعارض التسمية ، ولكن سأندهش إذا كان لذلك تأثير هائل على واجهات برمجة التطبيقات.

عندما أكتب مكتبة ، عادة ما أكون مدركًا تمامًا لما إذا كنت أرغب في إضافة إرسال إلى وظيفة في Base أو أريد الاحتفاظ بها منفصلة. أفترض أن معظم مؤلفي المكتبات الآخرين كذلك.

ninjaaron أعتقد أنه إذا كانت الاتفاقية الحالية تستخدم تنفيذًا محددًا لإرسال مثل

numpy.sin
sympy.sin

استخدام import numpy.sin as np_sin كخيار إضافي للمستخدم / المطور يجب ألا يؤثر على قاعدة الشفرة الحالية.
سيكون الشاغل الوحيد هو التأثير على وظيفة / واجهة العرض.

هل كانت هذه الصفحة مفيدة؟
0 / 5 - 0 التقييمات