如果您想了解如何确定是否为Selenium+Python加载了某些HTML元素?的相关知识,那么本文是一篇不可错过的文章,我们将对selenium判断进行全面详尽的解释,并且为您提供关于javascr
如果您想了解如何确定是否为Selenium + Python加载了某些HTML元素?的相关知识,那么本文是一篇不可错过的文章,我们将对selenium判断进行全面详尽的解释,并且为您提供关于javascript – 如何确定HTML元素是否具有伪元素?、Python + Selenium:如何在while循环中找到新出现的元素?、Python Selenium 使用小 HTML 查找具有动态 URL 和名称的元素、python selenium 判断元素是否可见的有价值的信息。
本文目录一览:- 如何确定是否为Selenium + Python加载了某些HTML元素?(selenium判断)
- javascript – 如何确定HTML元素是否具有伪元素?
- Python + Selenium:如何在while循环中找到新出现的元素?
- Python Selenium 使用小 HTML 查找具有动态 URL 和名称的元素
- python selenium 判断元素是否可见
如何确定是否为Selenium + Python加载了某些HTML元素?(selenium判断)
从这个链接,我假设首先应该将DOM整体加载到RAM中。
OM如何工作/如何加载?(以HTML格式)
但是后来我在Selenium中测试了超时异常。似乎甚至引发了超时异常,已经可以找到一些元素,因此它不是一个空对象。
但是我想知道,如何确保某些元素已经加载?例如HTML示例,如何确定所有<th>
元素都已加载?鉴于我实际上并不知道<th>
元素的数量。
代码试用:
driver = webdriver.Chrome()driver.set_page_load_timeout(10)try: driver.get(url) print(''load success!'')except TimeoutException: print(self.page_source)
HTML示例:
<table width="910" border="0" cellpadding="3" cellspacing="0" id="fth1_"> <thead> <tr align="center"> <th id="f13"><a href="t/?i=614&o=1">Symbol</a></th> <th id="f13"><a href="t/?i=614&o=2">Name</a></th> </tr> </thead></table>
答案1
小编典典根据你的代码试验使用的是 ChromeDriver 和 Chrome的浏览器 ,以 自动化
的步骤。配置完后,由于在通过配置的时间段内页面未完全加载,因此引发set_page_load_timeout(10)
了 超时
异常set_page_load_timeout()
。但是,当您调用print(self.page_source)
了部分呈现的HTMLDOM 中呈现的元素时,将对其进行检索。
现在关于您的单个查询:
How can I make sure some elements are already loaded?
:理想的 测试用例 将具有确定的步骤,例如,验证元素的存在,验证元素的可见性或验证元素的交互性(单击时)。从这个角度来看,验证 已经加载 的 元素 可能不包含所需的元素。因此,您需要将 搜索标准 范围缩小到某些确定的 范围, 而不是使用如此 广泛 的 搜索条件 ,例如- 页面标题
- 页面标题
- 警报的存在
- 元素的属性
- 元素的存在
- 一组元素的存在
- 元素的可见性
- 一组元素的可见性
- 元素的可点击性
- StalenessOf元素
- FrameToBeAvailableAndSwitchToIt
实现这些缩小 搜索条件 可以节省大量的_执行时间_的帮助下WebDriverWait
与inconjunctionexpected_conditions
]。
How can I make sure all elements are loaded?
:同样,我们的测试应仅集中在我们需要与之交互的元素上,而忽略验证与我们无关的其他元素的状态/条件。现在,根据上述两点,这是3种最常用的用 例 :
presence_of_element_located
:期望检查页面的DOM中是否存在元素。这并不一定意味着该元素是可见的。visibility_of_element_located
:期望检查元素是否存在于页面的DOM上并且可见。可见性意味着不仅显示元,而且其高度和宽度都大于0。element_to_be_clickable
:检查元素的期望是可见的并且已启用,因此您可以单击它。根据您提到的用 例 ,您可以使DOM树 中所有元素的 列表
<th>
可见,同时等待诱导 WebDriverWait 的可配置时间,如下所示:from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
headerList = WebDriverWait(driver, 20).until(EC.visibility_of_all_elements_located((By.XPATH, “//table[@class=’fth1_’ and @id=’fth1_’]/thead/tr//th”)))
注意 :此插图中使用的 xpath 是仅用于演示目的的样本 xpath 。
javascript – 如何确定HTML元素是否具有伪元素?
有没有办法确定给定的HTML元素是否在不调用的情况下应用了伪元素(:: before / :: after)
window.getComputedStyle(element,":before/:after");
编辑:答案是否定的
getComputedStyle的问题在于性能.我需要验证页面上的每个元素是否有伪元素 – 这就是性能非常关键的原因.
我试图从document.styleSheets访问cssRules以找到最后使用:: before或:: after的选择器,删除它并找到与其余选择器匹配的元素,但是这个解决方案有它自己的问题:
>无法访问来自不同域的styleSheets
>可能有成千上万的cssRules要检查(再次表现)
我还尝试比较元素的大小和偏移量有无元素,但没有任何效果.即使没有准确的方法,我也很乐意找到一种方法来削减一定数量的元素,至少检查30%.
当我确定该元素有一个伪元素时,我终于可以调用getComputedStyle来研究伪元素样式并进行更改.这部分完美有效.
编辑:我无法控制源页面.页面样式可以从不同的域动态上传.假设我的代码是内容脚本或库,例如必须将所有伪元素前景更改为基于该伪元素的其他CSS属性计算的某些颜色.
因此,主要问题是更改基于其他CSS属性,并且您无法在不实际检索伪元素的计算样式和计算更改的情况下为所有伪元素设置相同的样式.
例如,您有youtube.com页面,您需要找到所有伪元素和
>如果此伪元素具有背景图像,则缩放元素
>如果此伪元素只有文本,则将其颜色更改为红色
>等……
这种遍历元素的方法:
var allElements = document.getElementsByTagName("*");
for (var i = allElements.length; i--;) {
//var usedStyle = window.getComputedStyle(allElements[i],":before/:after");
...
}
每1ms大约有数千个元素.
并且getComputedStyle的调用不应该太慢,因为它获取在调用时已经计算的数据(在渲染文档上).
所以这一切都应该足够快.是的,它原则上是O(N)任务但是运行一次,对吧?
Python + Selenium:如何在while循环中找到新出现的元素?
对于您不拥有的网站,不要依赖类。 这是您的问题之一,否则将在将来。 依靠可以长时间保持静态的东西,例如在按钮上写的文字。 如果您确定下一个按钮将具有相同的类名,则只需存储找到的第一个按钮的类名以搜索其文本,然后在循环中进一步使用该类名即可。
确保这些按钮也没有加载到iframe中,这可能是个问题。 无论如何,请发布页面源代码的两个图像。第一次单击之前一个,在单击第一个按钮之后第二个。
谢谢。
Python Selenium 使用小 HTML 查找具有动态 URL 和名称的元素
如何解决Python Selenium 使用小 HTML 查找具有动态 URL 和名称的元素?
大家好!今天我正在使用 Python 3 和 Selenium Web 驱动程序。我在按元素查找时遇到问题。这是 HTML:
<a _ngcontent-pxc-c302=""href="/person/20d4a795d3fb43bdbee7e480df27b05b">michele regina</a>
目标是点击出现在列出的列中的名字。
名称随着每次页面刷新而变化。这带来了两个问题,即链接文本是名称并且它会发生变化,并且除了显示 /person/
我尝试了以下方法:
driver.find_element_by_css_selector("a.name ng-star-inserted").click()
driver.find_element_by_class_name("name ng-star-inserted").click()
这导致元素不是可点击错误。 我还通过复制和粘贴从 Google Inspector 复制的整个 XPath 来尝试 xpath...lol
driver.find_element_by_xpath(''/html/body/app-root/app-container/div/div/tc-app-view/div/div/div/ng-component/mat-sidenav-container/mat-sidenav-content/div/div[2]/tc-person-table-container/tc-collapse-expand[1]/section/tc-person-table/table/tbody/tr[1]/td[2]/tc-person-table-cell/a'').click()
它有时会起作用,这很奇怪,但我确信必须有更好的方法。非常感谢您!任何帮助表示赞赏!另外,我对 Python 非常陌生,我知道零 HTML,而且我也是堆栈的新手!谢谢!
解决方法
从给定的完整 xpath 中,您要查找的 a
标记位于 table
,section
,div
中。在这些标签中查找 ID 并跟踪 a
。
python selenium 判断元素是否可见
1 #在元素定位二次封装的基础上,封装判断元素是否可见,找到元素时返回True,找不到元素的时候抛出异常,返回False
2 def isElementPresent(self,locate_type,value):
3 try:
4 self.findElement(locate_type,value)
5 return True
6 except NoSuchElementException as e:
7 # print(e)
8 return False
今天的关于如何确定是否为Selenium + Python加载了某些HTML元素?和selenium判断的分享已经结束,谢谢您的关注,如果想了解更多关于javascript – 如何确定HTML元素是否具有伪元素?、Python + Selenium:如何在while循环中找到新出现的元素?、Python Selenium 使用小 HTML 查找具有动态 URL 和名称的元素、python selenium 判断元素是否可见的相关知识,请在本站进行查询。
在本文中,我们将详细介绍Python-set的各个方面,并为您提供关于如何实现?的相关解答,同时,我们也将为您带来关于CPython是什么?PyPy是什么?Python和这两个东西有什么关系呢?Python的底层使用什么语言实现?学习Python需要学习底层实现吗?、C#字符串的GetHashCode()如何实现?、JSP+Servlet实现在JSP显示excel(不用插件)如何实现?、Python 3中的Python 2 dict_items.sort()的有用知识。
本文目录一览:- Python-set()如何实现?(python中set()的用法)
- CPython是什么?PyPy是什么?Python和这两个东西有什么关系呢?Python的底层使用什么语言实现?学习Python需要学习底层实现吗?
- C#字符串的GetHashCode()如何实现?
- JSP+Servlet实现在JSP显示excel(不用插件)如何实现?
- Python 3中的Python 2 dict_items.sort()
Python-set()如何实现?(python中set()的用法)
我见过有人说set
python 中的对象具有O(1)成员资格检查。如何在内部实现它们以允许这样做?它使用哪种数据结构?该实现还有什么其他含义?
这里的每个答案都非常有启发性,但是我只能接受一个答案,因此,我将选择与原始问题最接近的答案。谢谢你的信息!
答案1
小编典典实际上,CPython的集合被实现为类似于带有伪值的字典(键是集合的成员)的字典,并且进行了一些优化,可以利用这种缺乏值的方式
因此,基本上,a set
使用哈希表作为其基础数据结构。这解释了O(1)成员资格检查,因为在哈希表中查找项目平均而言是O(1)操作。
如果你愿意的话,甚至可以浏览CPython源代码来查找集合,根据Achim Domma的说法,这主要是实现中的剪切粘贴dict
。
CPython是什么?PyPy是什么?Python和这两个东西有什么关系呢?Python的底层使用什么语言实现?学习Python需要学习底层实现吗?
回复内容:
首先Python是一种语言,因此根据其实现的不同,有Cpython, Jython, Pypy等。CPython即用C语言实现Python及其解释器(JIT编译器),Jython是用Java语言来实现,Pypy是用Python来实现(准确说是个Python子集)。就好像是英语也分美国、英国、澳大利亚等英语,其语法是想通的,但是类库的实现是不同的。
至于学习Python是否要学习底层实现,这个应该是不必要的,只从应用的角度来说,是没这个必要的。但是如果需要系统的掌握这门语言,那么了解底层实现更有助于了解这门语言的设计思想以及实现限制等方面。 1.CPython是最流行的Python实现
2.PyPy也是一种Python实现,实现的语言是RPython
3.Python:共产主义;CPython:苏联;PyPy:天朝
4.根据不同实现,用C(CPython)\C++(Pyston)\Java(Jython)\C#(IronPython)\Ruby\JS都有,成熟度非常不同
5.有必要。 Python解释器 Python是一门语言,有语法等规范。但是落实到具体实现上,就不一样了。用C实现的叫CPython,也是目前的参考实现。即最新的语言特性都是在这个上面先实现,Linux,OS X等自带的也是这个版本。用.NET实现的叫IronPython,Java的叫Jython,用Python实现的叫PyPy
C#字符串的GetHashCode()如何实现?
我只是好奇,因为我想它将对性能产生影响。是否考虑完整字符串?如果是,则在长字符串上会变慢。如果仅考虑字符串的一部分,则会导致性能下降(例如,如果仅考虑字符串的开头,则当HashSet主要包含相同的字符串时,它将导致性能下降。
答案1
小编典典遇到类似问题时,请确保获取参考源源代码。除了从反编译器中可以看到的内容之外,还有很多其他功能。选择与您的首选.NET目标相匹配的目标,该方法在版本之间已发生了很大变化。我将在此处重现它的.NET
4.5版本,该版本是从Source.NET 4.5 \ 4.6.0.0 \ net \ clr \ src \ BCL \ System \
String.cs \ 604718 \ String.cs检索的
public override int GetHashCode() {#if FEATURE_RANDOMIZED_STRING_HASHING if(HashHelpers.s_UseRandomizedStringHashing) { return InternalMarvin32HashString(this, this.Length, 0); } #endif // FEATURE_RANDOMIZED_STRING_HASHING unsafe { fixed (char *src = this) { Contract.Assert(src[this.Length] == ''\0'', "src[this.Length] == ''\\0''"); Contract.Assert( ((int)src)%4 == 0, "Managed string should start at 4 bytes boundary");#if WIN32 int hash1 = (5381<<16) + 5381; #else int hash1 = 5381;#endif int hash2 = hash1;#if WIN32 // 32 bit machines. int* pint = (int *)src; int len = this.Length; while (len > 2) { hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0]; hash2 = ((hash2 << 5) + hash2 + (hash2 >> 27)) ^ pint[1]; pint += 2; len -= 4; } if (len > 0) { hash1 = ((hash1 << 5) + hash1 + (hash1 >> 27)) ^ pint[0]; } #else int c; char *s = src; while ((c = s[0]) != 0) { hash1 = ((hash1 << 5) + hash1) ^ c; c = s[1]; if (c == 0) break; hash2 = ((hash2 << 5) + hash2) ^ c; s += 2; }#endif#if DEBUG // We want to ensure we can change our hash function daily. // This is perfectly fine as long as you don''t persist the // value from GetHashCode to disk or count on String A // hashing before string B. Those are bugs in your code. hash1 ^= ThisAssembly.DailyBuildNumber; #endif return hash1 + (hash2 * 1566083941); } } }
这可能超出了您的讨价还价,我将对代码进行一些注释:
if条件编译指令使此代码适应不同的.NET目标。FEATURE_XX标识符在其他地方定义,并在整个.NET源代码中关闭全部功能。当目标是框架的32位版本时定义WIN32,mscorlib.dll的64位版本是单独构建的,并存储在GAC的其他子目录中。
- s_UseRandomizedStringHashing变量启用哈希算法的安全版本,该版本旨在使程序员摆脱麻烦,因为这样做不明智,例如使用GetHashCode()生成密码或加密之类的哈希。通过app.exe.config文件中的条目启用它
- 该 固定 语句保持索引串便宜,避免了常规检查索引进行边界
- 第一个Assert确保字符串应以零结尾,以允许在循环中进行优化
- 第二个断言确保将字符串对齐为应为4的倍数的地址,以保持循环性能
- 手动展开该循环,对于32位版本,每个循环消耗4个字符。强制转换为int *是在int(32位)中存储2个字符(2 x 16位)的一种技巧。循环后的多余语句处理的字符串长度不是4的倍数。请注意,散列中可以包含零终止符,也可以不包含零终止符,长度不等于偶数。它查看字符串中的 所有 字符,并回答您的问题
- 循环的64位版本以不同的方式完成,由2手动展开。请注意,它以嵌入的零提前终止,因此不会查看所有字符。否则非常不常见。这很奇怪,我只能猜测这与可能很大的字符串有关。但是想不出一个实际的例子
- 最后的调试代码可确保框架中的任何代码都不依赖哈希代码在运行之间可重现。
- 哈希算法是相当标准的。值1566083941是一个幻数,是梅森捻线机中常见的素数。
JSP+Servlet实现在JSP显示excel(不用插件)如何实现?
最近有个需求,从后台oracle数据库中查询一堆数据,因为这些数据本来就是从excel读出来关键的存在数据库的,现在要提取出来一部分展示在JSP页面上,还是以excel的样式!
需求不能使用grid显示必须是excel,不进行增删改,只显示而已!
我查了一些方法都是需要付费的插件,但是貌似老板没有要付费的意思!所以那些付费的软件就不要推荐了!
大家有什么好的方法给点意见,谢谢大家。
Python 3中的Python 2 dict_items.sort()
我正在将一些代码从Python 2移植到3。这是Python 2语法中的有效代码:
def print_sorted_dictionary(dictionary):
items=dictionary.items()
items.sort()
在Python 3中,dict_items没有方法’sort’-如何在Python 3中解决此问题?
我们今天的关于Python-set和如何实现?的分享已经告一段落,感谢您的关注,如果您想了解更多关于CPython是什么?PyPy是什么?Python和这两个东西有什么关系呢?Python的底层使用什么语言实现?学习Python需要学习底层实现吗?、C#字符串的GetHashCode()如何实现?、JSP+Servlet实现在JSP显示excel(不用插件)如何实现?、Python 3中的Python 2 dict_items.sort()的相关信息,请在本站查询。
对于SimpleDateFormat toPattern在Java 9中的行为有所不同感兴趣的读者,本文将提供您所需要的所有信息,我们将详细讲解java中simpledateformat的作用,并且为您提供关于DateTimeFormatter与SimpleDateFormat、DateTimeFormatter和SimpleDateFormat有什么区别?、intern()在Java 6和Java 7中的行为有所不同、Java - 时间戳、Date、Calendar、SimpleDateFormat的宝贵知识。
本文目录一览:- SimpleDateFormat toPattern在Java 9中的行为有所不同(java中simpledateformat的作用)
- DateTimeFormatter与SimpleDateFormat
- DateTimeFormatter和SimpleDateFormat有什么区别?
- intern()在Java 6和Java 7中的行为有所不同
- Java - 时间戳、Date、Calendar、SimpleDateFormat
SimpleDateFormat toPattern在Java 9中的行为有所不同(java中simpledateformat的作用)
DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("SV", "SE"));((SimpleDateFormat) dateFormat).toPattern();
在Java 8中,此行产生,"yyyy-MM-dd"
而在Java 9中,它产生"y-MM-dd"
。
这对于我们的遗留代码有一些严重的问题,是否有某种方法可以还原行为?
答案1
小编典典 System.setProperty("java.locale.providers", "COMPAT,CLDR"); DateFormat dateFormat = DateFormat.getDateInstance(DateFormat.SHORT, new Locale("sv", "SE")); System.out.println(((SimpleDateFormat) dateFormat).toPattern());
在我的jdk-9.0.4上运行此打印
yyyy-MM-dd
您可能想-D
在命令行上使用属性设置,它不会有任何区别。
在Java
9中,来自Unicode联盟的通用语言环境数据存储库(CLDR)被用作语言环境数据的默认源,而在早期的Java版本中则不是这种情况。如上所述设置系统属性将启用Java
8行为。正如nullpointer在评论中所说,您可以在此处阅读更多内容:默认情况下使用CLDR Locale
Data。
罗勒·布尔克(Basil Bourque)的评论是正确的,习惯上将小写缩写用于语言,因此您可能应该指定sv
以确保不会混淆读者。
可能还会想知道y
模式中是否有一个或四个是否有任何区别。我阅读SimpleDateFormat
文档的方式是,y
将按照80-20规则来解释两位数的年份:它是在过去80年内或在接下来的20年之内。yyyy
将两位数字的年份解释为公元一世纪的一年。
。假设您的年份在4位数范围(1000到9999)之间,那么我认为这不是问题。
如果这仅适用于瑞典语言环境,则该代码的现代版本将给出相同的结果:
DateTimeFormatterBuilder.getLocalizedDateTimePattern( FormatStyle.SHORT, null, IsoChronology.INSTANCE, new Locale("SV", "SE")));
然而,对于一些语言环境(en-CY
塞浦路斯例如,英语)的结果不同DateFormat
来DateTimeFormatter
,所以如果你的目标是最大的向后兼容性,坚持使用过时的DateFormat
类。
DateTimeFormatter与SimpleDateFormat
日期格式化类:DateTimeFormatter与SimpleDateFormat
一、SimpleDateFormat类
- SimpleDateFormat是用于以对语言环境敏感的方式格式化和解析日期的具体类。
- SimpleDateFormat类的构造方法
NO | 构造器 | 描述 |
---|---|---|
1 | SimpleDateFormat() | SimpleDateFormat使用默认FORMAT语言环境的默认模式和日期格式符号 构造一个。 |
2 | SimpleDateFormat(Stringpattern) | SimpleDateFormat使用给定的模式和默认FORMAT语言环境的默认日期格式符号 构造一个。 |
3 | SimpleDateFormat(Stringpattern,DateFormatSymbolsformatSymbols) | SimpleDateFormat使用给定的模式和日期格式符号构造一个。 |
4 | SimpleDateFormat(Stringpattern,Localelocale) | SimpleDateFormat使用给定语言环境和给定语言环境的默认日期格式符号构造一个。 |
SimpleDateFormat为什么不是线程安全的?
- SimpleDateFormat类的方法没有使用synchronized来给共享变量加锁。
- SimpleDateFormat继承于DateFormat,下面我们看看我们用来格式化的format()方法的部分源码
- DateFormat.java
public final String format(Date date)
{
return format(date, new StringBuffer(),
DontCareFieldPosition.INSTANCE).toString();
}
public abstract StringBuffer format(Date date, StringBuffer toAppendTo,
FieldPosition fieldPosition);
- SimpleDateFormat.java
@Override
public StringBuffer format(Date date, StringBuffer toAppendTo,
FieldPosition pos)
{
// 如此轻易地使用内部变量,肯定不能线程安全
// 线程都对pos进行写操作,必然会影响其他线程的读操作
pos.beginIndex = pos.endIndex = 0;
return format(date, toAppendTo, pos.getFieldDelegate());
}
private StringBuffer format(Date date, StringBuffer toAppendTo,
FieldDelegate delegate) {
// Convert input date to time field list
// 这里已经彻底毁坏线程的安全性
calendar.setTime(date);
boolean useDateFormatSymbols = useDateFormatSymbols();
for (int i = 0; i < compiledPattern.length; ) {
int tag = compiledPattern[i] >>> 8;
int count = compiledPattern[i++] & 0xff;
if (count == 255) {
count = compiledPattern[i++] << 16;
count |= compiledPattern[i++];
}
switch (tag) {
case TAG_QUOTE_ASCII_CHAR:
toAppendTo.append((char)count);
break;
case TAG_QUOTE_CHARS:
toAppendTo.append(compiledPattern, i, count);
i += count;
break;
default:
subFormat(tag, count, delegate, toAppendTo, useDateFormatSymbols);
break;
}
}
return toAppendTo;
}
看源码不用全部看,只需要看重点,不然你会很难受,很耗费时间。SimpleDateFormat类中的format方法的一段代码calendar.setTime(date);
,从这我们可以看出来,如果我们把SimpleDateFormat定义成static成员变量,那么多个thread之间会共享这个SimpleDateFormat对象, 所以Calendar对象也会被共享。那么当有线程A,B操作该方法时,A线程已经给Calendar对象setTime了,但是这时A线程让出了cpu被B线程抢占了,这时B线程在给Calendar对象setTime一个值,然后A线程获得cpu处理,这时A线程以为使用的是它给setTime的值,其实这里的值已经被B线程更改了。这里就会出现线程不安全,因为这里的处理对象都被两个或者更多的线程公用,就会出现线程不安全,所以我们在开发时,尽量使用内部变量,不共享的变量。 3. 实例
package www.com.lining.dateformate;
import java.text.SimpleDateFormat;
import java.util.Locale;
public class DateTimeFormateTest1 {
private static SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
private static String date[] = { "01-Jan-1999", "09-Jan-2000", "08-Jan-2001", "07-Jan-2002", "06-Jan-2003",
"05-Jan-2004", "04-Jan-2005", "03-Jan-2006", "02-Jan-2007" };
public static void main(String[] args) {
for (int i = 0; i < date.length; i++) {
final int temp = i;
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
String str1 = date[temp];
String str2 = sdf.format(sdf.parse(str1));
System.out.println(Thread.currentThread().getName() + ", " + str1 + "," + str2);
if (!str1.equals(str2)) {
throw new RuntimeException(
Thread.currentThread().getName() + ", Expected " + str1 + " but got " + str2);
}
}
} catch (Exception e) {
throw new RuntimeException("parse failed", e);
}
}
}).start();
}
}
}
- 输出
- 一定要注意cpu的使用权都是需要去抢占的,所以就会出现多线程情况下,出现线程安全问题。
SimpleDateFormat线程不安全的解决方法
- 将SimpleDateFormat定义成局部变量,每次使用时在new 对象。但是每调用一次方法就会创建一个SimpleDateFormat对象,方法结束又要作为垃圾回收,很浪费资源。
- 加一把线程同步锁:synchronized(lock)
public class SyncDateFormatTest {
private static SimpleDateFormat sdf = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
private static String date[] = { "01-Jan-1999", "01-Jan-2000", "01-Jan-2001" };
public static void main(String[] args) {
for (int i = 0; i < date.length; i++) {
final int temp = i;
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
synchronized (sdf) {
String str1 = date[temp];
Date date = sdf.parse(str1);
String str2 = sdf.format(date);
System.out.println(Thread.currentThread().getName() + ", " + str1 + "," + str2);
if(!str1.equals(str2)){
throw new RuntimeException(Thread.currentThread().getName()
+ ", Expected " + str1 + " but got " + str2);
}
}
}
} catch (Exception e) {
throw new RuntimeException("parse failed", e);
}
}
}).start();
}
}
}
缺点是:每次都要等该锁释放其他的线程才能使用,性能差。 3. 使用ThreadLocal类
- 直接继承与Object类,该类提供了线程局部变量,这些变量不同于他们的普通对应物,因为访问某个变量的每个线程都有自己的局部变量,它独立于变量的初始化副本。
- 每个线程都将拥有自己的SimpleDateFormat对象副本。
public class DateUtil {
private static ThreadLocal<SimpleDateFormat> local = new ThreadLocal<SimpleDateFormat>();
public static Date parse(String str) throws Exception {
SimpleDateFormat sdf = local.get();
if (sdf == null) {
sdf = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
local.set(sdf);
}
return sdf.parse(str);
}
public static String format(Date date) throws Exception {
SimpleDateFormat sdf = local.get();
if (sdf == null) {
sdf = new SimpleDateFormat("dd-MMM-yyyy", Locale.US);
local.set(sdf);
}
return sdf.format(date);
}
}
public class ThreadLocalDateFormatTest {
private static String date[] = { "01-Jan-1999", "01-Jan-2000", "01-Jan-2001" };
public static void main(String[] args) {
for (int i = 0; i < date.length; i++) {
final int temp = i;
new Thread(new Runnable() {
@Override
public void run() {
try {
while (true) {
String str1 = date[temp];
Date date = DateUtil.parse(str1);
String str2 = DateUtil.format(date);
System.out.println(str1 + "," + str2);
if(!str1.equals(str2)){
throw new RuntimeException(Thread.currentThread().getName()
+ ", Expected " + str1 + " but got " + str2);
}
}
} catch (Exception e) {
throw new RuntimeException("parse failed", e);
}
}
}).start();
}
}
}
这样每个线程都有自己的副本对象SimpleDateFormat,所以每次不同的线程调用的都是自己的副本对象,不会改变其他线程的对象的。
二、DateTimeFormatter类
- jdk1.8中新增了 LocalDate 与 LocalDateTime等类来解决日期处理方法,同时引入了一个新的类DateTimeFormatter来解决日期格式化问题。
- LocalDateTime,DateTimeFormatter两个类都没有线程问题,只要你自己不把它们创建为共享变量就没有线程问题。
- 可以使用Instant代替 Date,LocalDateTime代替 Calendar,DateTimeFormatter 代替 SimpleDateFormat。
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy MM dd");
LocalDate date = LocalDate.parse("2017 06 17", formatter);
System.out.println(formatter.format(date));
- DateTimeFormatter.ofPattern(pattern)的实现
public static DateTimeFormatter ofPattern(String pattern) {
return new DateTimeFormatterBuilder().appendPattern(pattern).toFormatter();
}
public final class DateTimeFormatterBuilder extends Object
- TimeFormatterBuilder():用于创建日期时间格式化程序的生成器。
- TimeFormatterBuilder().appendPattern(pattern):将指定模式定义的元素追加到构建器,返回TimeFormatterBuilder对象。
- toFormatter():通过DateTimeFormatter使用默认语言环境创建来完成此构建器,获取DateTimeFormatter对象。
- 模式基于字母和符号的简单序列。模式用于使用ofPattern(String)和ofPattern(String, Locale)方法创建格式化程序 。例如, "d MMM uuuu"将2011-12-03的格式设置为“ 2011年12月3日”。从模式创建的格式化程序可以根据需要多次使用,它是不可变的并且是线程安全的。 例如:
LocalDate日期= LocalDate.now();
DateTimeFormatter formatter = DateTimeFormatter.ofPattern(“ yyyy MM dd”);
字符串文本= date.format(formatter);
LocalDate parsedDate = LocalDate.parse(text,formatter);
- 其中的LocalDate和LocalDateTime都可以去查看jdk1.8往上的版本api去学习。
DateTimeFormatter和SimpleDateFormat有什么区别?
DateTimeFormatter和SimpleDateFormat都是用于日期时间格式化和解析的类,但它们有以下几个区别:
1.线程安全性:
- DateTimeFormatter 是线程安全的,可以在多线程环境下共享和重用。
- SimpleDateFormat 不是线程安全的,不建议在多线程环境中共享和重用,除非使用适当的同步措施。
2.API 设计:
- DateTimeFormatter 是 Java 8 中引入的,并遵循了新的日期时间 API 的设计原则,提供了一致且易于使用的方法,支持更多的日期时间模式符号和灵活的格式化选项。
- SimpleDateFormat 是早期的 Java 日期时间 API(java.util.Date) 中的类,使用较老的设计风格,并且其 API 比较有限。
3.底层实现:
- DateTimeFormatter 使用基于解析器和格式化器的模型,底层使用 java.time.format.DateTimeFormatterBuilder 类来构建格式化模式。
- SimpleDateFormat 使用基于模式字符串的方式进行格式化和解析,底层使用 java.text.SimpleDateFormat 类。
以下是使用DateTimeFormatter和SimpleDateFormat的代码示例:
使用DateTimeFormatter示例代码:
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
public class DateTimeFormatterExample {
public static void main(String[] args) {
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
// 格式化日期时间
LocalDateTime now = LocalDateTime.now();
String formattedDateTime = formatter.format(now);
System.out.println("格式化后的日期时间:" + formattedDateTime);
// 解析日期时间
String dateTimeString = "2023-07-03 12:30:45";
LocalDateTime parsedDateTime = LocalDateTime.parse(dateTimeString, formatter);
System.out.println("解析后的日期时间:" + parsedDateTime);
}
}
打印结果:
格式化后的日期时间:2023-07-03 15:34:58
解析后的日期时间:2023-07-03T12:30:45
使用SimpleDateFormat示例代码:
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
public class SimpleDateFormatExample {
public static void main(String[] args) {
SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
// 格式化日期时间
Date now = new Date();
String formattedDateTime = sdf.format(now);
System.out.println("格式化后的日期时间:" + formattedDateTime);
// 解析日期时间
String dateTimeString = "2023-07-03 12:30:45";
try {
Date parsedDateTime = sdf.parse(dateTimeString);
System.out.println("解析后的日期时间:" + parsedDateTime);
} catch (ParseException e) {
e.printStackTrace();
}
}
}
打印结果:
格式化后的日期时间:2023-07-03 15:38:33
解析后的日期时间:Mon Jul 03 12:30:45 CST 2023
在这个示例中,我们分别使用了DateTimeFormatter和SimpleDateFormat来格式化和解析日期时间。它们的用法非常相似,但是需要注意的是,DateTimeFormatter是线程安全的,可以在多线程环境下共享和重用;而SimpleDateFormat不是线程安全的,不建议在多线程环境中共享和重用。
intern()在Java 6和Java 7中的行为有所不同
class Test { public static void main(String...args) { String s1 = "Good"; s1 = s1 + "morning"; System.out.println(s1.intern()); String s2 = "Goodmorning"; if (s1 == s2) { System.out.println("both are equal"); } }}
此代码在Java 6和Java 7中产生不同的输出。在Java 6中,s1==s2
条件返回false
,在Java
7中,s1==s2
返回true
。为什么?
为什么该程序在Java 6和Java 7中产生不同的输出?
答案1
小编典典似乎JDK7处理实习生的方式与以前不同。
我用版本1.7.0-b147进行了测试,结果“都是相等的”,但是用1,6.0_24执行它(相同的字节码)时,我没有得到消息。
它还取决于该String b2 =...
行在源代码中的位置。以下代码也不会输出该消息:
class Test { public static void main(String... args) { String s1 = "Good"; s1 = s1 + "morning"; String s2 = "Goodmorning"; System.out.println(s1.intern()); //just changed here s1.intern() and the if condition runs true if(s1 == s2) { System.out.println("both are equal"); } //now it works. }}
似乎intern
在其字符串池中找不到String之后,将实际实例s1插入池中。创建s2时,JVM正在使用该池,因此它获得与s1相同的引用。另一方面,如果首先创建s2,则该引用将存储到池中。
这可能是由于将永久字符串从Java堆的永久生成中移出的结果。
在这里找到:JDK
7中解决的重要RFE
在JDK 7中,不再将永久字符串分配给Java堆的永久代,而是分配给Java堆的主要部分(称为年轻代和旧代),以及由应用程序创建的其他对象。
。此更改将导致更多数据驻留在主Java堆中,而永久生成中的数据更少,因此可能需要调整堆大小。由于此更改,大多数应用程序只会看到相对较小的堆使用差异,但是加载许多类或大量使用String.intern()方法的大型应用程序将看到更大的差异。
不知道这是一个错误,以及从哪个版本开始……JLS 3.10.5声明
显式内联计算所得字符串的结果是与任何具有相同内容的现有文字字符串相同的字符串。
因此,问题是如何在编译时或执行时解释预先存在的内容:“ Goodmorning”是否预先存在?
我更喜欢7之前实现的方式…
Java - 时间戳、Date、Calendar、SimpleDateFormat
Java
package com.ikoo.demo;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
public class DateUtil {
public static void main(String[] args) {
/**
* 时间戳
* 1.System.currentTimeMillis()
* 2.new Date().getTime()
* 3.Calendar.getInstance().getTimeInMillis()
* P.S.
* Java获取时间戳精确到毫秒级,Unix中精确到秒级,所以Java获取的时间戳需要除以1000,就可以保证一致性
* Calendar.getInstance().getTimeInMillis() 耗时最多,这是因为Canlendar要处理时区问题
*/
System.out.println("System.currentTimeMillis(): " + System.currentTimeMillis());
System.out.println("new Date().getTime(): " + new Date().getTime());
System.out.println("Calendar.getInstance().getTimeInMillis(): " + Calendar.getInstance().getTimeInMillis());
System.out.println("----------");
/**
* 时间戳(日期)转换自定义日期格式
*/
long timeStamp = System.currentTimeMillis();
System.out.println("System.currentTimeMillis(): " + timeStamp);
Date date = new Date();
System.out.println("new Date(): " + date);
long dateTimaStamp = date.getTime();
System.out.println("date.getTime(): " + date.getTime());
String formatDate0 = DateUtil.timeStampToFormatDate(System.currentTimeMillis(), "yyyy-MM-dd HH:mm:ss");
System.out.println("formatDate0: " + formatDate0);
String formatDate1 = DateUtil.timeStampToFormatDate(new Date(), "yyyy-MM-dd HH:mm:ss");
System.out.println("formatDate1: " + formatDate1);
String formatDate2 = DateUtil.timeStampToFormatDate(new Date().getTime(), "yyyy-MM-dd HH:mm:ss");
System.out.println("formatDate2: " + formatDate2);
String formatDate3 = DateUtil.timeStampToFormatDate(Calendar.getInstance().getTime(), "yyyy-MM-dd HH:mm:ss");
System.out.println("formatDate3: " + formatDate3);
}
/**
* 时间戳转换为格式化日期
*
* @param dateObj 时间对象
* System.currentTimeMillis()
* new Date()
* new Date().getTime()
* Calendar.getInstance().getTimeInMillis()
* @param pattern 日期格式
* yyyy-MM-dd HH:mm:ss
* yyyy/MM/dd HH:mm:ss
* yyyy年MM月dd日 HH:mm:ss
* @return sdf.format(Object dateObj)
*/
public static String timeStampToFormatDate(Object dateObj, String pattern) {
SimpleDateFormat sdf = new SimpleDateFormat(pattern);
String formatDate = sdf.format(dateObj);
return formatDate;
}
}
控制台打印结果:
System.currentTimeMillis(): 1503660334272
new Date().getTime(): 1503660334274
Calendar.getInstance().getTimeInMillis(): 1503660334299
----------
System.currentTimeMillis(): 1503660334328
new Date(): Fri Aug 25 19:25:34 CST 2017
date.getTime(): 1503660334328
formatDate0: 2017-08-25 19:25:34
formatDate1: 2017-08-25 19:25:34
formatDate2: 2017-08-25 19:25:34
formatDate3: 2017-08-25 19:25:34
Process finished with exit code 0
关于SimpleDateFormat toPattern在Java 9中的行为有所不同和java中simpledateformat的作用的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于DateTimeFormatter与SimpleDateFormat、DateTimeFormatter和SimpleDateFormat有什么区别?、intern()在Java 6和Java 7中的行为有所不同、Java - 时间戳、Date、Calendar、SimpleDateFormat的相关信息,请在本站寻找。
如果您想了解如何在python中按创建日期对目录列表进行排序?的相关知识,那么本文是一篇不可错过的文章,我们将对python 创建日期进行全面详尽的解释,并且为您提供关于Python-如何对字符串列表进行排序?、Python-如何通过内部列表的特定索引对列表列表进行排序?、Python如何对元组列表进行排序?、Python如何对集合列表进行排序?的有价值的信息。
本文目录一览:- 如何在python中按创建日期对目录列表进行排序?(python 创建日期)
- Python-如何对字符串列表进行排序?
- Python-如何通过内部列表的特定索引对列表列表进行排序?
- Python如何对元组列表进行排序?
- Python如何对集合列表进行排序?
如何在python中按创建日期对目录列表进行排序?(python 创建日期)
获取目录中所有文件的列表的最佳方法是什么,按日期排序[创建| 修改],在Windows机器上使用python?
答案1
小编典典这@Greg Hewgill是答案的更详细的版本。这是最符合问题要求的。它区分了创建日期和修改日期(至少在Windows上如此)。
#!/usr/bin/env pythonfrom stat import S_ISREG, ST_CTIME, ST_MODEimport os, sys, time# path to the directory (relative or absolute)dirpath = sys.argv[1] if len(sys.argv) == 2 else r''.''# get all entries in the directory w/ statsentries = (os.path.join(dirpath, fn) for fn in os.listdir(dirpath))entries = ((os.stat(path), path) for path in entries)# leave only regular files, insert creation dateentries = ((stat[ST_CTIME], path) for stat, path in entries if S_ISREG(stat[ST_MODE]))#NOTE: on Windows `ST_CTIME` is a creation date # but on Unix it could be something else#NOTE: use `ST_MTIME` to sort by a modification datefor cdate, path in sorted(entries): print time.ctime(cdate), os.path.basename(path)
例:
$ python stat_creation_date.pyThu Feb 11 13:31:07 2009 stat_creation_date.py
答案2
小编典典过去,我是通过Python脚本确定目录中最后更新的文件的方式:
import globimport ossearch_dir = "/mydir/"# remove anything from the list that is not a file (directories, symlinks)# thanks to J.F. Sebastion for pointing out that the requirement was a list # of files (presumably not including directories) files = list(filter(os.path.isfile, glob.glob(search_dir + "*")))files.sort(key=lambda x: os.path.getmtime(x))
这应该可以根据文件mtime执行你想要的操作。
编辑:请注意,如果需要,还可以使用os.listdir()
代替glob.glob()
-我在原始代码中使用glob的原因是我想使用glob仅搜索具有特定集合的文件文件扩展名,glob()
更适合。要使用listdir,结果如下所示:
import ossearch_dir = "/mydir/"os.chdir(search_dir)files = filter(os.path.isfile, os.listdir(search_dir))files = [os.path.join(search_dir, f) for f in files] # add path to each filefiles.sort(key=lambda x: os.path.getmtime(x))
Python-如何对字符串列表进行排序?
如何解决Python-如何对字符串列表进行排序??
基本答案:
mylist = ["b", "C", "A"]
mylist.sort()
这会修改你的原始列表(即就地排序)。要获得列表的排序副本,而无需更改原始副本,请使用以下sorted()
函数:
for x in sorted(mylist):
print x
但是,上面的示例有些天真,因为它们没有考虑区域设置,而是执行区分大小写的排序。你可以利用可选参数key指定自定义排序顺序(使用cmp
,则是不推荐使用的解决方案,因为它必须多次评估- key每个元素仅计算一次)。
因此,要根据当前语言环境进行排序,并考虑到特定于语言的规则(这cmp_to_key
是functools
的帮助函数):
sorted(mylist, key=cmp_to_key(locale.strcoll))
最后,如果需要,你可以指定自定义语言环境进行排序:
import locale
locale.setlocale(locale.LC_ALL, ''en_US.UTF-8'') # vary depending on your lang/locale
assert sorted((u''Ab'', u''ad'', u''aa''),
key=cmp_to_key(locale.strcoll)) == [u''aa'', u''Ab'', u''ad'']
最后要注意的是:你将看到使用该lower()
方法的不区分大小写的排序示例-这些是不正确的,因为它们仅适用于ASCII字符集。对于任何非英语数据,这两个错误:
# this is incorrect!
mylist.sort(key=lambda x: x.lower())
# alternative notation, a bit faster, but still wrong
mylist.sort(key=str.lower)
解决方法
在Python中创建按字母顺序排序的列表的最佳方法是什么?
Python-如何通过内部列表的特定索引对列表列表进行排序?
我有一个清单。例如,
[[0,1,''f''],[4,2,''t''],[9,4,''afsd'']]
如果我想按内部列表的字符串字段对外部列表进行排序,那么你将如何在python中执行此操作?
答案1
小编典典这是itemgetter的工作
>>> from operator import itemgetter>>> L=[[0, 1, ''f''], [4, 2, ''t''], [9, 4, ''afsd'']]>>> sorted(L, key=itemgetter(2))[[9, 4, ''afsd''], [0, 1, ''f''], [4, 2, ''t'']]
也可以在此处使用lambda函数,但是在这种简单情况下,lambda函数的运行速度较慢
Python如何对元组列表进行排序?
从经验上讲,似乎Python的默认列表排序器在传递元组列表时将按每个元组中的第一个元素进行排序。那是对的吗?如果不是,按元组的第一个元素对元组列表进行排序的正确方法是什么?
Python如何对集合列表进行排序?
Python通过按顺序查看元组的元素来对元组列表进行排序。由于集合是无序的,Python如何对集合列表进行排序?
编辑:帖子中的问题和可接受的答案较为笼统,给出的文件也很深入。我的问题不是重复的。
关于如何在python中按创建日期对目录列表进行排序?和python 创建日期的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Python-如何对字符串列表进行排序?、Python-如何通过内部列表的特定索引对列表列表进行排序?、Python如何对元组列表进行排序?、Python如何对集合列表进行排序?等相关知识的信息别忘了在本站进行查找喔。
本文标签: