بالنسبة لنظام الوحدات ، يمكننا استيراد واستخدام وحدة برمز النقطة:
import ArgParse
...
ArgParse.add_argument(p, "--opt1")
...
يمكن أن يكون هذا مفيدًا لمنع تلوث مساحة الاسم. ولكن بسبب الإسهاب في أسماء الوحدات ، سيكون من الجيد أن يكون لديك أسماء مستعارة للوحدة:
import ArgParse as ap
...
ap.add_argument(p, "--opt1")
...
أدركت منذ دقائق أنه يمكنك القيام بما يلي:
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}
إنها قضية مختلفة عن هذه ، لكنها ذات صلة. هل علي أن
(أفترض أن فائدة مثل هذه الميزة ليست مثيرة للجدل ...)
تحرير : هذا يعمل الآن مع 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
@ 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
خاصان لأنهما يُستخدمان فقط لآثارهما الجانبية ، وفقط في المستوى الأعلى.
بالمناسبة ، نظرًا لأن هذه المشكلة كانت مفتوحة لفترة طويلة ، أتساءل عما إذا كان الفرز على استعداد لإعادة النظر فيه واتخاذ قرار. أود أن أدعو إلى الإغلاق ، منذ ذلك الحين
import Foo; const Bar = Foo
حلاً مثاليًا عندما لا يمانع المستخدم Foo
في مساحة الاسم ،سأقول أنه بعد كل هذا الوقت ، ما زلت أفتقد هذا (وأنا أيضًا أستخدم 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
كخيار إضافي للمستخدم / المطور يجب ألا يؤثر على قاعدة الشفرة الحالية.
سيكون الشاغل الوحيد هو التأثير على وظيفة / واجهة العرض.
التعليق الأكثر فائدة
كانت هذه المشكلة موجودة منذ وقت طويل ، على الرغم من أنه لا يزال يتعين مناقشة بعض الامتدادات ، فإن
نفسها تبدو معقولة جدًا.