参数通过 assignment 传递。这背后的理由是双重的:
所以:
为了更清楚,让我们举一些例子。
让我们尝试修改传递给方法的列表:
def try_to_change_list_contents(the_list): print('got', the_list) the_list.append('four') print('changed to', the_list) outer_list = ['one', 'two', 'three'] print('before, outer_list =', outer_list) try_to_change_list_contents(outer_list) print('after, outer_list =', outer_list)
输出:
before, outer_list = ['one', 'two', 'three'] got ['one', 'two', 'three'] changed to ['one', 'two', 'three', 'four'] after, outer_list = ['one', 'two', 'three', 'four']
由于传入的参数是对 的引用outer_list,而不是它的副本,我们可以使用 mutating list 方法对其进行更改,并将更改反映在外部范围中。
outer_list
现在让我们看看当我们尝试更改作为参数传入的引用时会发生什么:
def try_to_change_list_reference(the_list): print('got', the_list) the_list = ['and', 'we', 'can', 'not', 'lie'] print('set to', the_list) outer_list = ['we', 'like', 'proper', 'English'] print('before, outer_list =', outer_list) try_to_change_list_reference(outer_list) print('after, outer_list =', outer_list)
before, outer_list = ['we', 'like', 'proper', 'English'] got ['we', 'like', 'proper', 'English'] set to ['and', 'we', 'can', 'not', 'lie'] after, outer_list = ['we', 'like', 'proper', 'English']
由于the_list参数是按值传递的,因此为它分配一个新列表对方法外的代码可以看到没有任何影响。这the_list是outer_list引用的副本,我们the_list指向了一个新列表,但无法更改outer_list指向的位置。
the_list
它是不可变的,所以我们无法改变字符串的内容
现在,让我们尝试更改参考
def try_to_change_string_reference(the_string): print('got', the_string) the_string = 'In a kingdom by the sea' print('set to', the_string) outer_string = 'It was many and many a year ago' print('before, outer_string =', outer_string) try_to_change_string_reference(outer_string) print('after, outer_string =', outer_string)
before, outer_string = It was many and many a year ago got It was many and many a year ago set to In a kingdom by the sea after, outer_string = It was many and many a year ago
同样,由于the_string参数是按值传递的,因此为它分配一个新字符串对方法外部的代码没有任何影响。the_string是引用的副本,outer_string我们the_string指向了一个新字符串,但无法更改outer_string指向的位置。
the_string
outer_string
我希望这能澄清一点。
编辑:有人指出,这并没有回答@David 最初提出的问题,“我可以做些什么来通过实际引用传递变量吗?”。让我们继续努力。
正如@Andrea 的回答所示,您可以返回新值。这不会改变传递事物的方式,但可以让您获得想要的信息:
def return_a_whole_new_string(the_string): new_string = something_to_do_with_the_old_string(the_string) return new_string # then you could call it like my_string = return_a_whole_new_string(my_string)
如果您真的想避免使用返回值,您可以创建一个类来保存您的值并将其传递给函数或使用现有类,如列表:
def use_a_wrapper_to_simulate_pass_by_reference(stuff_to_change): new_string = something_to_do_with_the_old_string(stuff_to_change[0]) stuff_to_change[0] = new_string # then you could call it like wrapper = [my_string] use_a_wrapper_to_simulate_pass_by_reference(wrapper) do_something_with(wrapper[0])
虽然这看起来有点麻烦。
演示:http: //jsfiddle.net/arbel/pd9yB/1694/
这适用于任何动态文本或单个字符,并且都是自动化的。您需要做的就是在目标文本上添加一个类,剩下的就交给我们了。
此外,为盲人或视障人士的屏幕阅读器保留了原始文本的可访问性。
单个字符的解释:
纯 CSS。您需要做的就是将.halfStyleclass 应用于包含您想要半样式的字符的每个元素。
.halfStyle
对于包含字符的每个 span 元素,您可以创建一个数据属性,例如 here data-content="X",并在伪元素上使用content: attr(data-content);,因此.halfStyle:before该类将是动态的,您无需为每个实例硬编码它。
data-content="X"
content: attr(data-content);
.halfStyle:before
任何文本的解释:
只需将textToHalfStyle类添加到包含文本的元素。
textToHalfStyle
// jQuery for automated mode jQuery(function($) { var text, chars, $el, i, output; // Iterate over all class occurences $('.textToHalfStyle').each(function(idx, el) { $el = $(el); text = $el.text(); chars = text.split(''); // Set the screen-reader text $el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + text + '</span>'); // Reset output for appending output = ''; // Iterate over all chars in the text for (i = 0; i < chars.length; i++) { // Create a styled element for each character and append to container output += '<span aria-hidden="true" class="halfStyle" data-content="' + chars[i] + '">' + chars[i] + '</span>'; } // Write to DOM only once $el.append(output); }); }); .halfStyle { position: relative; display: inline-block; font-size: 80px; /* or any font size will work */ color: black; /* or transparent, any color */ overflow: hidden; white-space: pre; /* to preserve the spaces from collapsing */ } .halfStyle:before { display: block; z-index: 1; position: absolute; top: 0; left: 0; width: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow: hidden; color: #f00; } <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <p>Single Characters:</p> <span class="halfStyle" data-content="X">X</span> <span class="halfStyle" data-content="Y">Y</span> <span class="halfStyle" data-content="Z">Z</span> <span class="halfStyle" data-content="A">A</span> <hr/> <p>Automated:</p> <span class="textToHalfStyle">Half-style, please.</span>
(JSFiddle 演示)
*使用此解决方案,您可以单独和独立地设置左右部件的样式*。
一切都是一样的,只有更高级的 CSS 才能发挥作用。
现在我们知道什么是可能的,让我们创建一些变化。
Show code snippet
(JSFiddle 演示和samtremaine.co.uk上)
可以在同一页面上的所需元素上使用定制的不同 Half-Style 样式集。您可以定义多个样式集并告诉插件使用哪一个。
该插件data-halfstyle="[-CustomClassName-]"在目标.textToHalfStyle元素上使用数据属性并自动进行所有必要的更改。
data-halfstyle="[-CustomClassName-]"
.textToHalfStyle
因此,只需在包含文本的元素上添加textToHalfStyleclass 和 data 属性data-halfstyle="[-CustomClassName-]"。该插件将完成剩下的工作。
此外,CSS 样式集的类定义与[-CustomClassName-]上面提到的部分匹配并链接到.halfStyle,所以我们将有.halfStyle.[-CustomClassName-]
[-CustomClassName-]
.halfStyle.[-CustomClassName-]
jQuery(function($) { var halfstyle_text, halfstyle_chars, $halfstyle_el, halfstyle_i, halfstyle_output, halfstyle_style; // Iterate over all class occurrences $('.textToHalfStyle').each(function(idx, halfstyle_el) { $halfstyle_el = $(halfstyle_el); halfstyle_style = $halfstyle_el.data('halfstyle') || 'hs-base'; halfstyle_text = $halfstyle_el.text(); halfstyle_chars = halfstyle_text.split(''); // Set the screen-reader text $halfstyle_el.html('<span style="position: absolute !important;clip: rect(1px 1px 1px 1px);clip: rect(1px, 1px, 1px, 1px);">' + halfstyle_text + '</span>'); // Reset output for appending halfstyle_output = ''; // Iterate over all chars in the text for (halfstyle_i = 0; halfstyle_i < halfstyle_chars.length; halfstyle_i++) { // Create a styled element for each character and append to container halfstyle_output += '<span aria-hidden="true" class="halfStyle ' + halfstyle_style + '" data-content="' + halfstyle_chars[halfstyle_i] + '">' + halfstyle_chars[halfstyle_i] + '</span>'; } // Write to DOM only once $halfstyle_el.append(halfstyle_output); }); }); /* start half-style hs-base */ .halfStyle.hs-base { position: relative; display: inline-block; font-size: 80px; /* or any font size will work */ overflow: hidden; white-space: pre; /* to preserve the spaces from collapsing */ color: #000; /* for demo purposes */ } .halfStyle.hs-base:before { display: block; z-index: 1; position: absolute; top: 0; width: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ pointer-events: none; /* so the base char is selectable by mouse */ overflow: hidden; color: #f00; /* for demo purposes */ } /* end half-style hs-base */ /* start half-style hs-horizontal-third */ .halfStyle.hs-horizontal-third { /* base char and also the bottom 1/3 */ position: relative; display: inline-block; font-size: 80px; /* or any font size will work */ color: transparent; overflow: hidden; white-space: pre; /* to preserve the spaces from collapsing */ color: #f0f; text-shadow: 2px 2px 0px #0af; /* for demo purposes */ } .halfStyle.hs-horizontal-third:before { /* creates the top 1/3 */ display: block; z-index: 2; position: absolute; top: 0; height: 33.33%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow: hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #f00; /* for demo purposes */ text-shadow: 2px -2px 0px #fa0; /* for demo purposes */ } .halfStyle.hs-horizontal-third:after { /* creates the middle 1/3 */ display: block; position: absolute; z-index: 1; top: 0; height: 66.66%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow: hidden; pointer-events: none; /* so the base char is selectable by mouse */ color: #000; /* for demo purposes */ text-shadow: 2px 2px 0px #af0; /* for demo purposes */ } /* end half-style hs-horizontal-third */ /* start half-style hs-PeelingStyle, by user SamTremaine on Stackoverflow.com */ .halfStyle.hs-PeelingStyle { position: relative; display: inline-block; font-size: 68px; color: rgba(0, 0, 0, 0.8); overflow: hidden; white-space: pre; transform: rotate(4deg); text-shadow: 2px 1px 3px rgba(0, 0, 0, 0.3); } .halfStyle.hs-PeelingStyle:before { /* creates the left part */ display: block; z-index: 1; position: absolute; top: -0.5px; left: -3px; width: 100%; content: attr(data-content); overflow: hidden; pointer-events: none; color: #FFF; transform: rotate(-4deg); text-shadow: 0px 0px 1px #000; } /* end half-style hs-PeelingStyle */ /* start half-style hs-KevinGranger, by user KevinGranger on StackOverflow.com*/ .textToHalfStyle.hs-KevinGranger { display: block; margin: 200px 0 0 0; text-align: center; } .halfStyle.hs-KevinGranger { font-family: 'Libre Baskerville', serif; position: relative; display: inline-block; width: 1; font-size: 70px; color: black; overflow: hidden; white-space: pre; text-shadow: 1px 2px 0 white; } .halfStyle.hs-KevinGranger:before { display: block; z-index: 1; position: absolute; top: 0; width: 50%; content: attr(data-content); /* dynamic content for the pseudo element */ overflow: hidden; color: white; } /* end half-style hs-KevinGranger <script src="https://ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js"></script> <p> <span class="textToHalfStyle" data-halfstyle="hs-base">Half-style, please.</span> </p> <p> <span class="textToHalfStyle" data-halfstyle="hs-horizontal-third">Half-style, please.</span> </p> <p> <span class="textToHalfStyle" data-halfstyle="hs-PeelingStyle">Half-style, please.</span> </p> <p style="background-color:#000;"> <span class="textToHalfStyle" data-halfstyle="hs-KevinGranger">Half-style, please.</span> </p>