想了解如何将文件和文件夹添加到GitHub存储库中?的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于如何将文件和文件夹添加到github存储库中的相关问题,此外,我们还将为您介绍关于git上
想了解如何将文件和文件夹添加到 GitHub 存储库中?的新动态吗?本文将为您提供详细的信息,我们还将为您解答关于如何将文件和文件夹添加到 github 存储库中的相关问题,此外,我们还将为您介绍关于git 上传代码到GitHub 以及git删除github上文件和文件的命令、jquery – 如何在github上的存储库中的子文件夹中搜索特定的单词或条目、php – 将文件夹中的所有文件和文件夹移动到另一个文件夹?、ruby-on-rails – 将文件夹添加到资产管道路径?的新知识。
本文目录一览:- 如何将文件和文件夹添加到 GitHub 存储库中?(如何将文件和文件夹添加到 github 存储库中)
- git 上传代码到GitHub 以及git删除github上文件和文件的命令
- jquery – 如何在github上的存储库中的子文件夹中搜索特定的单词或条目
- php – 将文件夹中的所有文件和文件夹移动到另一个文件夹?
- ruby-on-rails – 将文件夹添加到资产管道路径?
如何将文件和文件夹添加到 GitHub 存储库中?(如何将文件和文件夹添加到 github 存储库中)
我在 GitHub 上创建了一个帐户——我是新手——我在添加文件时遇到了问题。我已经添加了readme.txt
. 此外,我还有 3 个其他 PHP
文件和一个包含图像的文件夹。
如何添加文件和文件夹?我尝试了它,git pull
因为git push origin -u master
向我显示了一个错误。
答案1
小编典典您可以使用git add
, example git add README
,git add <folder>/*
甚至添加文件git add *
然后用于git commit -m "<Message>"
提交文件
最后git push -u origin master
推送文件。
当您进行修改运行时git status
,它会为您提供修改的文件列表,添加它们git add*
用于所有内容,或者您可以单独指定每个文件,然后git commit -m <message>
最后,git push -u originmaster
示例 - 假设您创建了一个文件 README,运行git status
会为您提供
$ git status# On branch master# Untracked files:# (use "git add <file>..." to include in what will be committed)## README
运行git add README
,文件被暂存以进行提交。然后git status
再次运行,它应该会给您 - 文件已添加并准备好提交。
$ git status# On branch master# Changes to be committed:# (use "git reset HEAD <file>..." to unstage)## new file: README#nothing added to commit but untracked files present (use "git add" to track)
然后运行git commit -m ''Added README''
$ git commit -m ''Added README''[master 6402a2e] Added README 0 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 README
最后,推送仓库git push -u origin master
的远程分支。master``origin
$ git push -u origin masterCounting objects: 4, done.Delta compression using up to 2 threads.Compressing objects: 100% (2/2), done.Writing objects: 100% (3/3), 267 bytes, done.Total 3 (delta 1), reused 0 (delta 0)To xxx@xxx.com:xxx/xxx.git 292c57a..6402a2e master -> masterBranch master set up to track remote branch master from origin.
文件已成功推送到远程存储库。
运行 agit pull origin master
以确保您已吸收任何上游更改
$ git pull origin masterremote: Counting objects: 12, done.remote: Compressing objects: 100% (4/4), done.remote: Total 8 (delta 4), reused 7 (delta 3)Unpacking objects: 100% (8/8), done.From xxx.com:xxx/xxx * branch master -> FETCH_HEADUpdating e0ef362..6402a2eFast-forward public/javascript/xxx.js | 5 ++--- 1 files changed, 2 insertions(+), 3 deletions(-) create mode 100644 README
如果您不想将上游更改与本地存储库合并,请运行git fetch
以获取更改,然后git merge
合并更改。gitpull
只是fetch
和的组合merge
。
我个人使用过 gitimmersion - http://gitimmersion.com/来了解
git 的曲线,这是一个分步指南,如果您需要一些文档和帮助
git 上传代码到GitHub 以及git删除github上文件和文件的命令
Git入门
如果你完全没有接触过Git,你现在只需要理解通过Git的语法(敲入一些命令)就可以将代码上传到远程的仓库或者下载到本地的仓库(服务器),可知我们此时应该有两个仓库,就是两个放代码的地方,一个是本地,一个是远程的(如Github)。企业或者团队可以通过Git来对项目进行管理,每个程序员只需将自己的本地仓库写好的代码上传到远程仓库,另一个程序员就可以下载到本地仓库了。今天我们就从Git终端软件的安装开始,再这之前我也简单介绍一下Github。
Git上传代码
一、准备工作
1、注册一个github账号。
2.下载windows上git终端,类似shell工具,下载地址:http://msysgit.github.io/
3、安装方法,打开文件,一路点击Next即可
4、安装完成。
接下来就可以进入正题啦~
二、开始上传
1.登陆你的github,在github新建一个仓库,输入你的仓库名。
1.新建本地仓库:现在进入你想要上传到github上的的项目,右键选择文件夹会出现git GUI here和git Base here,前者选择指定文件夹用来创建本地仓库,后者用来进入git命令行
现在我们先选择git GUI here 创建我们的本地仓库。
2.绑定用户:现在进入项目的文件夹,右键选择git Base here,之后我们就进入git客户端的命令行啦,
因为Git是分布式版本控制系统,所以需要填写用户名和邮箱作为一个标识,用户和邮箱为你github注册的账号和邮箱
ps : git config –global 参数,有了这个参数,表示你这台机器上所有的Git仓库都会使用这个配置,当然你也可以对某个仓库指定的不同的用户名和邮箱
3.为Github账户设置SSH key(可忽略)
此处链接跳转:http://blog.csdn.net/hustpzb/article/details/8230454/
ps:其实第三步也可以跳过,对于初学者来说直接使用http上传就行,了解之后再去了解ssh加密上传,这里我就简单将降http上传,其实没什么太大区别,后面的步骤都一样
4.提交本地代码
输入$ git init开始创建啦
1)、在本地仓库目录新建一个你要上传的文件,比如我上传的文件是readme.txt
2)、在命令行输入,将要上传的文件上传到本地仓库:
$ git add readme.txt
$ git commit -m 'readme.txt'
如图所示:
4)、关联远程仓库
这个链接就是github上新建仓库的链接
$ git remote add origin master https://github.com/starForlove/weixin-buycar
3)、push代码到服务器上
经过上面已经把代码传到本地仓库了,接下来要做的很简单,只要把本地的代码传到服务器上就行了。
$ git push origin master
接下来它会提示你输入用户名和密码,用户名就是你在github上注册的名字,密码就是你的登录密码
4)、现在你已经上传成功了,登陆你的github账户,就可以看到你上传的文件(readme.txt就是我上传的啦~)
5)如果出现上传不成功,可能是因为你远程仓库已经存在文件,和你本地仓库文件不一致,或者你本地仓库的文件不是最新的,这个时候,你需要执行下面这行命令:
$ git pull origin master
将远程仓库的文件重新下载到本地仓库,然后再次执行
$ git push origin master
三、删除远程仓库不想要的文件
ps:我们在上传项目后如果上传了你不想要的文件怎么办?很操蛋的在github上我们是不能直接删除仓库的文件,我们只能通过终端命令来删除我们不想要的文件或者目录
Git 如何删除远程服务器文件同时保留本地文件
在上传工程到git上时,有时候会把本地的一些eclipse配置文件传到服务器上,这时你先删除本地,再同步服务器,显然是不合理的。git提供了一个好的解决方法,可以直接删除服务器文件,同时不影响本地文件,命令如下
1.删除服务器文件,本地保留
此时github上已经不存在了
2.删除远程useless 文件夹,本地保留
一定要注意,删除文件夹要使用-r 参数
git rm --cached -r useless
git commit -m "remove directory from remote repository"
git push
关于git的使用就介绍到这里啦,学而时习之,确实是一个不错的学习方式,将自己学习过的东西通过博客整理出来真的大大加深了我的掌握程度。
jquery – 如何在github上的存储库中的子文件夹中搜索特定的单词或条目
作为一个例子,我需要在以下位置的jquery测试套件中搜索函数名“clean”或“clean”或类似函数的测试用例 –
https://github.com/jquery/jquery/tree/master/test
我知道有一些过滤器,如repo:和path:由github提供,但不知道如何使用它们.
此外,我对于在类似问题上发布的答案不满意 –
Search a github repository for the file defining a given function
我知道我可以将它分叉到我的本地机器并在那里进行搜索,但我不想下载整个存储库只是为了搜索它.我只需要在github网站上在线搜索它.
提前致谢 !!
解决方法
关键是指定用户/ reponame,而不是reponame:
repo:hadley/ggplot2
结合使用路径参数的通配符,我只选择一个带有this query的参数:
repo:hadley/ggplot2 facet_wrap path:inst/*.r
因此,对于path,关键是添加一个通配符(似乎没有记录在任何地方).
路径:inst / alone不起作用.路径:*或路径:*.r会.
来自评论:
I need to find “
beforeSend
” entry which is in this file – “jquery / test / unit / ajax.js
” atgithub.com/jquery/jquery/blob/master/test/unit/ajax.js
but when I firerepo:jeresig/jquery beforeSend path:jquery/test/unit*.js
in the advance search I don’t get any results.
I am also confused which user should I use as jquery has many contributors like John Resig,timmywil
在这种情况下:
> repo是jquery / jquery(这里不需要用户名)
> path:使用的指令不得重复repo名称:so,path:test / unit * .js,not path:jquery / test / unit * .js
repo:jquery/jquery beforeSend path:test/unit*.js
将工作,provide 4 results within JQuery Code.
php – 将文件夹中的所有文件和文件夹移动到另一个文件夹?
我想将文件夹中的所有文件和文件夹移动到另一个文件夹.我找到了将文件夹中的所有文件复制到另一个文件夹的代码.
move all files in a folder to another
// Get array of all source files
$files = scandir("source");
// Identify directories
$source = "source/";
$destination = "destination/";
// Cycle through all source files
foreach ($files as $file) {
if (in_array($file, array(".",".."))) continue;
// If we copied this successfully, mark it for deletion
if (copy($source.$file, $destination.$file)) {
$delete[] = $source.$file;
}
}
// Delete all successfully-copied files
foreach ($delete as $file) {
unlink($file);
}
如何更改此项以将此文件夹中的所有文件夹和文件移动到另一个文件夹.
解决方法:
这是我用的
// Function to remove folders and files
function rrmdir($dir) {
if (is_dir($dir)) {
$files = scandir($dir);
foreach ($files as $file)
if ($file != "." && $file != "..") rrmdir("$dir/$file");
rmdir($dir);
}
else if (file_exists($dir)) unlink($dir);
}
// Function to copy folders and files
function rcopy($src, $dst) {
if (file_exists ( $dst ))
rrmdir ( $dst );
if (is_dir ( $src )) {
mkdir ( $dst );
$files = scandir ( $src );
foreach ( $files as $file )
if ($file != "." && $file != "..")
rcopy ( "$src/$file", "$dst/$file" );
} else if (file_exists ( $src ))
copy ( $src, $dst );
}
用法
rcopy($source , $destination );
另一个示例没有删除目标文件或文件夹
function recurse_copy($src,$dst) {
$dir = opendir($src);
@mkdir($dst);
while(false !== ( $file = readdir($dir)) ) {
if (( $file != '.' ) && ( $file != '..' )) {
if ( is_dir($src . '/' . $file) ) {
recurse_copy($src . '/' . $file,$dst . '/' . $file);
}
else {
copy($src . '/' . $file,$dst . '/' . $file);
}
}
}
closedir($dir);
}
请参阅:http://php.net/manual/en/function.copy.php了解更多有用的例子
谢谢
ruby-on-rails – 将文件夹添加到资产管道路径?
有没有办法我可以动态地告诉rails加载哪个主题/主题名称/资产文件夹我想要的?我们使用设置逻辑来设置哪个主题是活动的.所以如果我的主题设置为“google”,ApplicationController然后从路径加载文件:
app/themes/google/locales/*.yml app/themes/google/views
我想要做的是拥有清单文件,
app/themes/google/assets/stylesheets/application.css
很容易访问布局,就像在app / views / layouts文件中一样:
= stylesheet_link_tag "application"
有办法我可以做到吗?或者我们需要手动将资产移动到实际的资产目录中?
解决方法
require "#{Rails.root}/app/models/settings.rb" config.assets.paths << "#{Rails.root}/app/themes/#{Settings.theme}/assets/stylesheets" config.assets.paths << "#{Rails.root}/app/themes/#{Settings.theme}/assets/images" config.assets.paths << "#{Rails.root}/app/themes/#{Settings.theme}/assets/javascripts"
关于如何将文件和文件夹添加到 GitHub 存储库中?和如何将文件和文件夹添加到 github 存储库中的介绍已经告一段落,感谢您的耐心阅读,如果想了解更多关于git 上传代码到GitHub 以及git删除github上文件和文件的命令、jquery – 如何在github上的存储库中的子文件夹中搜索特定的单词或条目、php – 将文件夹中的所有文件和文件夹移动到另一个文件夹?、ruby-on-rails – 将文件夹添加到资产管道路径?的相关信息,请在本站寻找。
如果您对SciPy 和 NumPy 之间的关系感兴趣,那么本文将是一篇不错的选择,我们将为您详在本文中,您将会了解到关于SciPy 和 NumPy 之间的关系的详细内容,我们还将为您解答scipy与numpy的区别的相关问题,并且为您提供关于cvxpy 和 numpy 之间的版本冲突:“针对 API 版本 0xe 编译的模块,但此版本的 numpy 是 0xd”、Linux下Python科学计算包numpy和SciPy的安装、macOS 安装 pypy3 + numpy + scipy 实录、Numpy / Scipy中的卷积计算的有价值信息。
本文目录一览:- SciPy 和 NumPy 之间的关系(scipy与numpy的区别)
- cvxpy 和 numpy 之间的版本冲突:“针对 API 版本 0xe 编译的模块,但此版本的 numpy 是 0xd”
- Linux下Python科学计算包numpy和SciPy的安装
- macOS 安装 pypy3 + numpy + scipy 实录
- Numpy / Scipy中的卷积计算
SciPy 和 NumPy 之间的关系(scipy与numpy的区别)
SciPy 似乎在其自己的命名空间中提供了 NumPy 的大部分(但不是全部 [1])函数。换句话说,如果有一个名为
的函数numpy.foo
,几乎肯定会有一个scipy.foo
. 大多数时候,两者看起来完全一样,甚至经常指向同一个函数对象。
有时,它们是不同的。举一个最近出现的例子:
numpy.log10
是一个ufunc,它为负参数返回 NaN;scipy.log10
返回负参数的复数值,并且看起来不是 ufunc。
log
关于,log2
和也可以这样说logn
,但关于log1p
[2] 则不然。
另一方面,numpy.exp
对于scipy.exp
同一个 ufunc
来说似乎是不同的名称。scipy.log1p
和也是如此numpy.log1p
。
另一个例子是numpy.linalg.solve
vs scipy.linalg.solve
。它们是相似的,但后者比前者提供了一些额外的功能。
为什么会出现明显的重复?如果这是numpy
对scipy
命名空间的大规模导入,为什么会有细微的行为差异和缺少的功能?是否有一些总体逻辑可以帮助消除混乱?
[1] numpy.min
、numpy.max
和numpy.abs
其他一些在命名空间中没有对应scipy
项。
[2] 使用 NumPy 1.5.1 和 SciPy 0.9.0rc2 进行测试。
答案1
小编典典上次我检查它时,scipy__init__
方法执行了一个
from numpy import *
以便在导入 scipy 模块时将整个 numpy 命名空间包含在 scipy 中。
log10
您描述的行为很有趣,因为 这两个 版本都来自 numpy. 一个是 a ufunc
,另一个是numpy.lib
函数。为什么
scipy 比 scipy 更喜欢库函数ufunc
,我不知道。
编辑:事实上,我可以回答这个log10
问题。查看 scipy__init__
方法,我看到了这个:
# Import numpy symbols to scipy name spaceimport numpy as _numfrom numpy import oldnumericfrom numpy import *from numpy.random import rand, randnfrom numpy.fft import fft, ifftfrom numpy.lib.scimath import *
您在 scipy 中获得的log10
功能来自numpy.lib.scimath
. 查看该代码,它说:
"""Wrapper functions to more user-friendly calling of certain math functionswhose output data-type is different than the input data-type in certaindomains of the input.For example, for functions like log() with branch cuts, the versions in thismodule provide the mathematically valid answers in the complex plane:>>> import math>>> from numpy.lib import scimath>>> scimath.log(-math.exp(1)) == (1+1j*math.pi)TrueSimilarly, sqrt(), other base logarithms, power() and trig functions arecorrectly handled. See their respective docstrings for specific examples."""
似乎该模块覆盖了sqrt
, log
, log2
, logn
, log10
, power
, arccos
,arcsin
和的基本
numpy ufunc arctanh
。这解释了您所看到的行为。这样做的根本设计原因可能隐藏在某处的邮件列表帖子中。
cvxpy 和 numpy 之间的版本冲突:“针对 API 版本 0xe 编译的模块,但此版本的 numpy 是 0xd”
如何解决cvxpy 和 numpy 之间的版本冲突:“针对 API 版本 0xe 编译的模块,但此版本的 numpy 是 0xd”?
我正在尝试升级一些软件包并为现有的 Python 程序整合我的 requirements.txt
,以便将其移至 docker 容器。
这个容器将基于 tensorflow docker 容器,这决定了我必须使用的一些包版本。我们在 windows 下工作,我们希望能够在我们的机器上本地运行该程序(至少在一段时间内)。所以我需要找到一个适用于 docker 和 Windows 10 的配置。
Tensorflow 2.4.1
需要 numpy~=1.19.2
。使用 numpy 1.20
时,pip
会抱怨 numpy 1.20
是一个不兼容的版本。
但是在使用 numpy~=1.19.2
时,导入 cvxpy
时出现以下错误。 pip
安装所有软件包都很好:
RuntimeError: module compiled against API version 0xe but this version of numpy is 0xd
Traceback (most recent call last):
File "test.py",line 1,in <module>
import cvxpy
File "c:\Projekte\algo5\venv\lib\site-packages\cvxpy\__init__.py",line 18,in <module>
from cvxpy.atoms import *
File "c:\Projekte\algo5\venv\lib\site-packages\cvxpy\atoms\__init__.py",line 20,in <module>
from cvxpy.atoms.geo_mean import geo_mean
File "c:\Projekte\algo5\venv\lib\site-packages\cvxpy\atoms\geo_mean.py",in <module>
from cvxpy.utilities.power_tools import (fracify,decompose,approx_error,lower_bound,File "c:\Projekte\algo5\venv\lib\site-packages\cvxpy\utilities\power_tools.py",in <module>
from cvxpy.atoms.affine.reshape import reshape
File "c:\Projekte\algo5\venv\lib\site-packages\cvxpy\atoms\affine\reshape.py",in <module>
from cvxpy.atoms.affine.hstack import hstack
File "c:\Projekte\algo5\venv\lib\site-packages\cvxpy\atoms\affine\hstack.py",in <module>
from cvxpy.atoms.affine.affine_atom import AffAtom
File "c:\Projekte\algo5\venv\lib\site-packages\cvxpy\atoms\affine\affine_atom.py",line 22,in <module>
from cvxpy.cvxcore.python import canonInterface
File "c:\Projekte\algo5\venv\lib\site-packages\cvxpy\cvxcore\python\__init__.py",line 3,in <module>
import _cvxcore
ImportError: numpy.core.multiarray Failed to import
重现步骤:
1.)
在 Windows 10 下创建一个新的 Python 3.8 venv
并激活它
2.) 通过 requirements.txt
安装以下 pip install -r requirements.txt
:
cvxpy
numpy~=1.19.2 # tensorflow 2.4.1 requires this version
3.) 通过 test.py
python test.py
import cvxpy
if __name__ == ''__main__'':
pass
如果我想使用 tensorflow 2.3
,也会发生同样的事情。在这种情况下需要 numpy~=1.18
,错误完全相同。
搜索错误发现很少的命中,可悲的是没有帮助我。
我该怎么做才能解决这个问题?
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
Linux下Python科学计算包numpy和SciPy的安装
系统环境:
OS:RedHat5
Python版本:Python2.7.3
gcc版本:4.1.2
各个安装包版本:
scipy-0.11.0
numpy-1.6.2
nose-1.2.1
lapack-3.4.2
atlas-3.10.0
依赖关系:scipy的安装需要依赖于numpy、lapack、atlas(后两者都是线性代数工具包),而numpy和sci的测试程序的运行又依赖于nose,因此,整个安装过程必须要按顺序执行的,否则是无法执行下去的。
安装步骤:
1、安装nose
这个安装比较简单,解压缩nose的安装文件,进入nose的目录,直接运行setup.py即可:
tar -zxvf nose-1.2.1.tar.gz
cd nose-1.2.1
python setup.py install
2、安装lapack
由于最新版本的ATLAS可以直接集成lapack的安装压缩文件进行编译,因此,如果仅在python下使用的话,可以不用安装lapack。只需要下载压缩文件:lapack-3.4.2.tgz 即可。
3、安装ATLAS
这个的安装主要是配置一些选项,包括配置成64位库文件、位置无关的以及共享的链接库。详细的配置说明在atlas安装包 doc/ 下的pdf文件中。可查阅。
下面是我的安装过程:
tar -jxvf atlas3.10.0.tar.bz2
cd ATLAS
mkdir obj64
../configure -b 64 -Fa alg -fPIC -shared --prefix=/配置atlas的安装路径/atlas --with-netlib-lapack-tarfile=/lapack安装压缩文件存放的目录/lapack-3.4.2.tgz
(注:这个配置时间非常长,在Core i7 处理上,大概1个小时左右)
make
(下面是一些检查过程,保证没有问题之后再进行安装)
make check
make time
make install
至此,atlas安装完成。不过我们要记录下编译过程中所用的fortran编译器类型,这个信息在下面安装numpy和scipy的时候要用。还是在目录 obj64/ 下,执行
fgrep "F77 =" Make.inc
可以看到 F77 =
gfortran
记下这个编译器类型 gfortran.
4、安装numpy
numpy和scipy的安装过程都要显式的指明所用fortran编译器的类型,而且要与前面编译atlas时一致(在本文中即:gfortran),这一点非常重要,否则很多功能都会出错。
首先配置numpy目录下的site.cfg文件,指明atlas库的位置:
tar -zxvf numpy-1.6.2.tar.gz
cd numpy-1.6.2
cp site.cfg.example site.cfg
vim site.cfg
配置成如下格式:
[DEFAULT]
library_dirs = /usr/local/lib:/atlas的安装目录/atlas/lib
include_dirs = /usr/local/include:/atlas的安装目录/include
[blas_opt]
libraries = f77blas, cblas, atlas
[lapack_opt]
libraries = lapack, f77blas, cblas, atlas
[amd]
amd_libs = amd
[umfpack]
umfpack_libs = umfpack
接下来配置安装numpy所需要的Fortran编译器类型:
如果前面得到的Fortran编译器是gfortran的话,执行:
python setup.py build --fcompiler=gnu95
如果前面得到的Fortran编译器是g77的话,执行:
python setup.py build --fcompiler=gnu
然后执行
python setup.py install
安装完成
5、安装scipy
与安装numpy类似:
tar -zxvf scipy-0.11.0.tar.gz
cd scipy-0.11.0
vim site.cfg
配置成如下格式:
[DEFAULT]
library_dirs = /usr/local/lib:/atlas的安装目录/atlas/lib
include_dirs = /usr/local/include:/atlas的安装目录/include
[blas_opt]
libraries = f77blas, cblas, atlas
[lapack_opt]
libraries = lapack, f77blas, cblas, atlas
[amd]
amd_libs = amd
[umfpack]
umfpack_libs = umfpack
接下来配置安装numpy所需要的Fortran编译器类型:
如果前面得到的Fortran编译器是gfortran的话,执行:
python setup.py build --fcompiler=gnu95
如果前面得到的Fortran编译器是g77的话,执行:
python setup.py build --fcompiler=gnu
然后执行
python setup.py install
安装完成
然后可以在python下执行相应的测试程序:
python
>>> import nose
>>> import numpy
>>> import scipy
>>> numpy.test('full')
>>> scipy.test('full')
REF:
http://blog.sina.com.cn/s/blog_62dfdc740101aoo6.html
macOS 安装 pypy3 + numpy + scipy 实录
pypy 是一个支持 JIT 技术的 python 解释器实现,在某些任务上可以期待有比 cpython 更好的性能。但由于很多 python 包使用了特殊的 cpython 扩展接口,难以被 cpython 支持。特别是机器学习、科学计算流行的软件包,现在通常通过 anaconda 直接安装预编译包,难以支持 pypy. 一直好奇 pypy 在科学计算任务上会不会比 cpython 有优势,折腾了一晚上在 macOS 上安装了 pypy3 + numpy + scipy + matplotlib + scikit-learn + matplotlib, 在这里记录一下。
首先需要安装 pypy3 本身和编译器。可以通过 homebrew 安装:
brew install pypy3 gcc g++ gfortran
此时 pypy3 & pip 已经可以使用。可以使用 pypy3 命令替代 python3 命令运行一些脚本:
pip_pypy3 install package_name
pypy3 # start pypy3
注意,如果当前有 conda env, virtualenv 处于激活状态,先将其 deactivate. 有时候 pypy3 没有正确设置环境变量,会有一些警告,但在我的测试过程中只有警告,没有出现错误。以及,pypy3 默认安装带的包比较少,可能会出现各种 ImportError, 一般可以使用 pip_pypy3 安装对应的包解决。
「纯 python 软件包」的安装一般可以成功,只有 numpy 这种带有 C 扩展、还需要链接其他库的包安装比较麻烦。为了安装 numpy, 首先需要安装某个数学加速库。这里建议安装 OpenBLAS. 直接安装预编译的 OpenBLAS 似乎是不行的,可能是由于预编译的编译器版本与本地不一致。因此直接从 github 拉取最新版并编译安装:
git clone https://github.com/xianyi/OpenBLAS.git
cd OpenBLAS
make
# default install into /opt/OpenBLAS
sudo make install
注意,anaconda 里的 numpy 链接的是 intel mkl. 可以尝试搜索从 intel 官网安装这个软件包,作为 root 安装时,这个软件包会被安装在 opt/intel/mkl
. 我没有尝试链接 intel mkl, 不知道能否成功。
之后编译安装 numpy & scipy. 这两个软件包从 pip 安装会失败,因此仍然从 github 拉取源码。这里以 numpy 为例,scipy 是同一个组织的软件包,安装步骤完全相同。
# install wheel at first
pip_pypy3 install wheel
git clone https://github.com/numpy/numpy.git
从 pip 安装失败是因为链接不到 OpenBLAS. 从一篇博客了解到,需要在 numpy 源代码根目录下添加一个文件 site.cfg
, 指定 OpenBLAS 位置:
[DEFAULT]
library_dirs = /opt/OpenBLAS/lib
include_dirs = /opt/OpenBLAS/include
[atlas]
atlas_libs = openblas
libraries = openblas
[openblas]
libraries = openblas
library_dirs = /opt/OpenBLAS/lib
include_dirs = /opt/OpenBLAS/include
scipy 编译时也需要在其根目录下创建一个同样的文件,可以直接把 numpy 目录下的该文件复制过去。然后可以编译、安装。
cd numpy # or scipy
pypy3 setup.py build
pypy3 setup.py install
这些编译过程可能需要花几分钟时间。numpy & scipy 安装成功后,其他的常见软件包 matplotlib, jupyter, scikit-learn 等的安装可以直接通过 pip_pypy3.
之后,如果想启动 ipython, 由于环境变量可能不正确,可能要通过以下命令:
pypy3 -m IPython
至此,基于 pypy3 的科学计算 & 机器学习环境安装成功 ~
pypy3 在某些情景下比 cpython 要快,但在我的项目上,它不仅没有变快,反而变慢了。。对于类似于脚本的短时运行的科学计算项目,pypy3 优势可能不明显,也有可能是我的打开方式有什么问题。。
Numpy / Scipy中的卷积计算
对我正在进行的一些计算工作进行性能分析,结果表明我程序中的一个瓶颈是基本上实现了此功能的函数(np
is numpy
,sp
is scipy
):
def mix1(signal1,signal2):
spec1 = np.fft.fft(signal1,axis=1)
spec2 = np.fft.fft(signal2,axis=1)
return np.fft.ifft(spec1*spec2,axis=1)
这两个信号的形状为(C,N)
,其中C
是数据集的数量(通常少于20个),并且N
是每组样本的数量(大约5000个)。每个集合(行)的计算完全独立于任何其他集合。
我认为这只是一个简单的卷积,因此我尝试将其替换为:
def mix2(signal1,signal2):
outputs = np.empty_like(signal1)
for idx,row in enumerate(outputs):
outputs[idx] = sp.signal.convolve(signal1[idx],signal2[idx],mode='same')
return outputs
…只是看看我是否得到了相同的结果。但是我没有,我的问题是:
- 为什么不?
- 有没有更好的方法来计算的等效值
mix1()
?
(我意识到,mix2
可能不会保持原样更快,但是这可能是并行化的一个很好的起点。)
这是我用来快速检查此内容的完整脚本:
import numpy as np
import scipy as sp
import scipy.signal
N = 4680
C = 6
def mix1(signal1,axis=1)
def mix2(signal1,mode='same')
return outputs
def test(num,chans):
sig1 = np.random.randn(chans,num)
sig2 = np.random.randn(chans,num)
res1 = mix1(sig1,sig2)
res2 = mix2(sig1,sig2)
np.testing.assert_almost_equal(res1,res2)
if __name__ == "__main__":
np.random.seed(0x1234ABCD)
test(N,C)
我们今天的关于SciPy 和 NumPy 之间的关系和scipy与numpy的区别的分享已经告一段落,感谢您的关注,如果您想了解更多关于cvxpy 和 numpy 之间的版本冲突:“针对 API 版本 0xe 编译的模块,但此版本的 numpy 是 0xd”、Linux下Python科学计算包numpy和SciPy的安装、macOS 安装 pypy3 + numpy + scipy 实录、Numpy / Scipy中的卷积计算的相关信息,请在本站查询。
在本文中,我们将带你了解在Json.Net中序列化属性,但不要反序列化属性在这篇文章中,我们将为您详细介绍在Json.Net中序列化属性,但不要反序列化属性的方方面面,并解答net json序列化常见的疑惑,同时我们还将给您一些技巧,以帮助您实现更有效的.NET中JSON数据进行序列化和反序列化操作分析、.NET中JSON的序列化和反序列化的几种方式、.NET中XML序列化和反序列化常用类和属性小结、ASP.NET中JSON的序列化和反序列化。
本文目录一览:- 在Json.Net中序列化属性,但不要反序列化属性(net json序列化)
- .NET中JSON数据进行序列化和反序列化操作分析
- .NET中JSON的序列化和反序列化的几种方式
- .NET中XML序列化和反序列化常用类和属性小结
- ASP.NET中JSON的序列化和反序列化
在Json.Net中序列化属性,但不要反序列化属性(net json序列化)
虽然我已经找到了许多方法来反序列化特定属性,同时又防止它们序列化,但我正在寻找相反的行为。
我发现了很多反问题:
使属性反序列化但不使用json.net序列化
我可以指示Json.NET反序列化(而不是序列化)特定属性吗?
JSON.Net-
仅在序列化时使用JsonIgnoreAttribute(但在反序列化时不使用)
我如何才能序列化一个特定的属性,但又防止其反序列化回POCO?有没有可以用来装饰特定属性的属性?
基本上,我正在寻找一种与ShouldSerialize *方法等效的反序列化方法。
我知道我可以编写一个自定义转换器,但是这样做似乎有点过头了。
编辑:
这里还有一些背景。这背后的原因是我的课看起来像:
public class Address : IAddress{ /// <summary> /// Gets or sets the two character country code /// </summary> [JsonProperty("countryCode")] [Required] public string CountryCode { get; set; } /// <summary> /// Gets or sets the country code, and province or state code delimited by a vertical pipe: <c>US|MI</c> /// </summary> [JsonProperty("countryProvinceState")] public string CountryProvinceState { get { return string.Format("{0}|{1}", this.CountryCode, this.ProvinceState); } set { if (!string.IsNullOrWhiteSpace(value) && value.Contains("|")) { string[] valueParts = value.Split(''|''); if (valueParts.Length == 2) { this.CountryCode = valueParts[0]; this.ProvinceState = valueParts[1]; } } } } [JsonProperty("provinceState")] [Required] public string ProvinceState { get; set; }}
我需要CountryProvinceState
用于请求的属性,但是我不希望它反序列化并触发设置程序逻辑。
答案1
小编典典最简单的方法是将real属性标记为,[JsonIgnore]
并创建一个get-
only代理属性:
/// <summary> /// Gets or sets the country code, and province or state code delimited by a vertical pipe: <c>US|MI</c> /// </summary> [JsonIgnore] public string CountryProvinceState { get { return string.Format("{0}|{1}", this.CountryCode, this.ProvinceState); } set { if (!string.IsNullOrWhiteSpace(value) && value.Contains("|")) { string[] valueParts = value.Split(''|''); if (valueParts.Length == 2) { this.CountryCode = valueParts[0]; this.ProvinceState = valueParts[1]; } } } } [JsonProperty("countryProvinceState")] string ReadCountryProvinceState { get { return CountryProvinceState; } }
如果需要,代理属性可以是私有的。
更新资料
如果必须对许多类中的许多属性执行此操作,则创建自己的ContractResolver
用于检查自定义属性的属性可能会更容易。如果找到,则该属性将表示该属性为仅获取:
[System.AttributeUsage(System.AttributeTargets.Property, AllowMultiple = false)]public class GetOnlyJsonPropertyAttribute : Attribute{}public class GetOnlyContractResolver : DefaultContractResolver{ protected override JsonProperty CreateProperty(MemberInfo member, MemberSerialization memberSerialization) { var property = base.CreateProperty(member, memberSerialization); if (property != null && property.Writable) { var attributes = property.AttributeProvider.GetAttributes(typeof(GetOnlyJsonPropertyAttribute), true); if (attributes != null && attributes.Count > 0) property.Writable = false; } return property; }}
然后像这样使用它:
[JsonProperty("countryProvinceState")][GetOnlyJsonProperty]public string CountryProvinceState { get; set; }
然后:
var settings = new JsonSerializerSettings { ContractResolver = new GetOnlyContractResolver() }; var address = JsonConvert.DeserializeObject<Address>(jsonString, settings);
.NET中JSON数据进行序列化和反序列化操作分析
可以使用datacontractjsonserializer类将类型实例序列化为json字符串,并将json字符串反序列化为类型实例。 datacontractjsonserializer在system.runtime.serialization.json命名空间下
,.NET Framework 3.5包含在System.ServiceModel.Web.dll中,需要添加对其的引用;.NET Framework 4在System.Runtime.Serialization中。
利用DataContractJsonSerializer序列化和反序列化的代码:
1: using System; 2: using System.Collections.Generic; 3: using System.Linq; 4: using System.Web; 5: using System.Runtime.Serialization.Json; 6: using System.IO; 7: using System.Text; 8: 9: /// <summary> 10: /// JSON序列化和反序列化辅助类 11: /// </summary> 12: public class JsonHelper 13: { 14: /// <summary> 15: /// JSON序列化 16: /// </summary> 17: public static string JsonSerializer<T>(T t) 18: { 19: DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); 20: MemoryStream ms = new MemoryStream(); 21: ser.WriteObject(ms, t); 22: string jsonString = Encoding.UTF8.GetString(ms.ToArray()); 23: ms.Close(); 24: return jsonString; 25: } 26: 27: /// <summary> 28: /// JSON反序列化 29: /// </summary> 30: public static T JsonDeserialize<T>(string jsonString) 31: { 32: DataContractJsonSerializer ser = new DataContractJsonSerializer(typeof(T)); 33: MemoryStream ms = new MemoryStream(Encoding.UTF8.GetBytes(jsonString)); 34: T obj = (T)ser.ReadObject(ms); 35: return obj; 36: } 37: }
序列化Demo:
简单对象Person:
1: public class Person 2: { 3: public string Name { get; set; } 4: public int Age { get; set; } 5: }
序列化为JSON字符串:
1: protected void Page_Load(object sender, EventArgs e) 2: { 3: Person p = new Person(); 4: p.Name = "张三"; 5: p.Age = 28; 6: 7: string jsonString = JsonHelper.JsonSerializer<Person>(p); 8: Response.Write(jsonString); 9: }
输出结果:
{"Age":28,"Name":"张三"}
反序列化Demo:
1: protected void Page_Load(object sender, EventArgs e) 2: { 3: string jsonString = "{\"Age\":28,\"Name\":\"张三\"}"; 4: Person p = JsonHelper.JsonDeserialize<Person>(jsonString); 5: }
ASP.NET中的JSON序列化和反序列化还可以使用JavaScriptSerializer,在 System.Web.Script.Serializatioin命名空间下,需引用System.Web.Extensions.dll.也可以使用 JSON.NET.
以上就是.NET中JSON数据进行序列化和反序列化操作分析的详细内容,更多请关注php中文网其它相关文章!
.NET中JSON的序列化和反序列化的几种方式
一、什么是JSON
JSON(JavaScript Object Notation, JS 对象简谱) 是一种轻量级的数据交换格式。它基于 ECMAScript (欧洲计算机协会制定的js规范)的一个子集,采用完全独立 于编程语言的文本格式来存储和表示数据。简洁和清晰的层次结构使得JSON 成为理想的数据交换语言。 易于人阅读和编写,同时也易于机器解析和生成,并有效地提升 网络传输效率。
是JavaScript用来处理数据的一种格式,大部分是用来处理JavaScript和web服务器端之间的数据交换,把后台web服务器的数据传递到前台,然后使用JavaScript进 行处理,例如ajax等,是独立于语言和平台的轻量级的数据交换格式。
二、JSON语法
1、JSON语法规则
JS 语言中,一切都是对象。因此,任何支持的类型都可以通过 JSON 来表示,例如字符串、数字、对象、数组等。但是对象和数组是比较特殊且常用的两种类型:
- 对象表示为键值对
- 数据由逗号分隔
- 花括号保存对象
- 方括号保存数组
对象:对象在JS中是使用花括号包裹{}起来的内容,数据结构为{key1:value1, key2:value2, ...}的键值对结构。在面向对象的语言中,key为对象的属性, value为对应的值。键名可以使用整数和字符串来表示。值的类型可以是任意类型。
{"firstName": "Brett", "lastName": "McLaughlin"}
数组:数组在JS中是方括号[]包裹起来的内容,数据结构为[".NET", "Javascript", "Python", ...]的索引结构。在JS中,数组是一种比较特殊的数据类型,它也可 以像对象那样使用键值对,但还是索引使用得多。同样,值的类型可以是任意类型。
{ "people": [{ "firstName": "zhang", "lastName": "san" }, { "firstName": "li", "lastName": "si" } ] }
2、JSON 键/值对
JSON键值对是用来保存JS对象的一种方式,和JS对象的写法也大同小异,键/值对组合中的键名写在前面并用双引号""包裹,使用冒号:分隔,然后紧接着值: { " firstName " : " Json " }
, 这很容易理解,等价于这条 JavaScript 语句: {firstName : " Json " }
。
3、JSON 与 JS 对象的关系
JS对象的关系,可以这么理解:JSON 是 JS 对象的字符串表示法,它使用文本表示一个 JS 对象的信息,本质是一个字符串。如:
var obj = {a: ''Hello'', b: ''World''}; //这是一个对象,注意键名也是可以使用引号包裹的 var json = ''{"a": "Hello", "b": "World"}''; //这是一个 JSON 字符串,本质是一个字符串
4、JSON 和 JS 对象互转
要实现从对象转换为 JSON 字符串,使用 JSON.stringify() 方法:
var json = JSON.stringify({a: ''Hello'', b: ''World''}); //结果是 ''{"a": "Hello", "b": "World"}''
要实现从 JSON 转换为对象,使用 JSON.parse() 方法:
var obj = JSON.parse(''{"a": "Hello", "b": "World"}''); //结果是 {a: ''Hello'', b: ''World''}
三、Json序列化方式
1、JavaScriptSerializer
使用JavaScriptSerializer方式需要引入的命名空间,这个在程序集System.Web.Extensions.dll.中。
using System.Web.Script.Serialization;
PS: 可用[ScriptIgnore] 标记不序列化的属性
Code:
public ActionResult GetJsonDemo() { //对象 DataModel model = new DataModel(); model.ID = 1; model.Name = "ZhangSan"; model.Sex = "女"; model.Age = 18; //对象序列化Json string strJson= JsonHelper.ObjectToJson(model); //Json反序列化对象 model= JsonHelper.JsonToObject<DataModel>(strJson); string strContent = "对象序列化:" + strJson + "\n"+ "反序列化值:" + model.Name + " " + model.Sex + " " + model.Age; return Content(strContent); }
JsonHelper:
public class JsonHelper { #region 第一种 JavaScriptSerializer //使用JavaScriptSerializer方式需要引入的命名空间,这个在程序集System.Web.Extensions.dll.中 //using System.Web.Script.Serialization; //注:可用[ScriptIgnore] 标记不序列化的属性 /// <summary> /// 序列化 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static string ObjectToJson(object obj) { JavaScriptSerializer jsonSerialize = new JavaScriptSerializer(); return jsonSerialize.Serialize(obj); } /// <summary> /// 反序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="strJson"></param> /// <returns></returns> public static T JsonToObject<T>(string strJson) { JavaScriptSerializer jsonSerialize = new JavaScriptSerializer(); //jsonSerialize.Deserialize<dynamic>(strJson); //取值model["Name"]; 要使用索引取值,不能使用对象.属性 return jsonSerialize.Deserialize<T>(strJson); } #endregion }
Result:
2、JSON.NET
使用Json.NET类库需要引入的命名空间 using Newtonsoft.Json;
PS: 可用[JsonIgnore]标记不序列化的属性
Code:
public ActionResult GetJsonDemo() { //对象 DataModel model = new DataModel(); model.ID = 2; model.Name = "LiSi"; model.Sex = "男"; model.Age = 20; //对象序列化Json string strJson = JsonHelper.ObjectToJson(model); //Json反序列化对象 model = JsonHelper.JsonToObject<DataModel>(strJson); string strContent = "对象序列化:" + strJson + "\n" + "反序列化值:" + model.Name + " " + model.Sex + " " + model.Age; return Content(strContent); }
JsonHelper:
/// <summary> /// Json 帮助类 /// </summary> public class JsonHelper { #region 第二种 JSON.NET //使用Json.NET类库需要引入的命名空间 using Newtonsoft.Json; //注:可用[JsonIgnore]标记不序列化的属性 /// <summary> /// 序列化 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static string ObjectToJson(object obj) { return JsonConvert.SerializeObject(obj); } /// <summary> /// 反序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="strJson"></param> /// <returns></returns> public static T JsonToObject<T>(string strJson) { return JsonConvert.DeserializeObject<T>(strJson); } #endregion }
Result:
3、DataContractJsonSerializer
使用DataContractJsonSerializer方式需要引入的命名空间,在System.Runtime.Serialization.dll.中。
using System.Runtime.Serialization.Json;
实体中的契约[DataMember],[DataContract],是使用DataContractJsonSerializer序列化和反序列化必须要加的,对于其他两种方式可加可不加。
PS: 可用[IgnoreDataMember] 标记不序列化的属性
Code:
public ActionResult GetJsonDemo() { //对象 DataModel model = new DataModel(); model.ID = 3; model.Name = "Wangwu"; model.Sex = "女"; model.Age = 22; //对象序列化Json string strJson = JsonHelper.ObjectToJson(model); //Json反序列化对象 model = JsonHelper.JsonToObject<DataModel>(strJson); string strContent = "对象序列化:" + strJson + "\n" + "反序列化值:" + model.Name + " " + model.Sex + " " + model.Age; return Content(strContent); }
JsonHelper:
/// <summary> /// Json 帮助类 /// </summary> public class JsonHelper { #region 第三种 DataContractJsonSerializer //使用DataContractJsonSerializer方式需要引入的命名空间,在System.Runtime.Serialization.dll.中 //using System.Runtime.Serialization.Json; //注:可用[IgnoreDataMember] 标记不序列化的属性 //实体中的契约[DataMember],[DataContract],是使用DataContractJsonSerializer序列化和反序列化必须要加的 //对于其他两种方式不必加,也可以的。 /// <summary> /// 序列化 /// </summary> /// <param name="obj"></param> /// <returns></returns> public static string ObjectToJson(object obj) { using (MemoryStream stream = new MemoryStream()) { DataContractJsonSerializer jsonSerialize = new DataContractJsonSerializer(obj.GetType()); jsonSerialize.WriteObject(stream, obj); return Encoding.UTF8.GetString(stream.ToArray()); } } /// <summary> /// 反序列化 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="strJson"></param> /// <returns></returns> public static T JsonToObject<T>(string strJson) { using (MemoryStream stream = new MemoryStream(Encoding.UTF8.GetBytes(strJson))) { DataContractJsonSerializer jsonSerialize = new DataContractJsonSerializer(typeof(T)); return (T)jsonSerialize.ReadObject(stream); } } #endregion }
Result:
PS: DataModel
[DataContract] public class DataModel { [DataMember] public int ID { get; set; } [DataMember] public string Name { get; set; } [DataMember] public string Sex { get; set; } [DataMember] public int Age { get; set; } }
四、总结
1、JSON序列化有三种方式
- JavaScriptSerializer类
- JSON.NET类库
- DataContractJsonSerializer类
2、尽量使用JSON.NET(开源)来序列化和反序列化,性能好。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
- Python 之 Json序列化嵌套类方式
- Python 将json序列化后的字符串转换成字典(推荐)
- SpringBoot Redis配置Fastjson进行序列化和反序列化实现
- jQuery序列化form表单数据为JSON对象的实现方法
- 特殊字符的json序列化总结大全
- golang如何自定义json序列化应用详解
- C#实体对象序列化成Json并让字段的首字母小写的两种解决方法
- JSON序列化Redis读取出错问题解决方案
.NET中XML序列化和反序列化常用类和属性小结
序列化和反序列化是指什么?
序列化(seriallization): 将对象转化为便于传输的数据格式, 常见的序列化格式:二进制格式,字节数组,json字符串,xml字符串。
反序列化(deseriallization):将序列化的数据恢复为对象的过程。
XmlSerializer类
该类用一种高度松散耦合的方式提供串行化服务。你的类不需要继承特别的基类,而且它们也不需要实现特别的接口。相反,你只需在你的类或者这些类的公共域以及读/写属性里加上自定义的特性。XmlSerializer通过反射机制读取这些特性并用它们将你的类和类成员映射到xml元素和属性(在对象和 XML 文档之间进行序列化和反序列化操作)。
.NET-XML序列化和反序列化简单示例代码
using System.IO; using System.Xml.Serialization; namespace Practices.Common { public class SimpleSerializer { /// <summary> /// Model实体对象序列化为XML字符串 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="t">Model实体对象</param> /// <returns></returns> public static string SerializeXMLL<T>(T t) { using (StringWriter sw = new StringWriter()) { XmlSerializer xmlSerializer = new XmlSerializer(t.GetType()); xmlSerializer.Serialize(sw, t); return sw.ToString(); } } /// <summary> /// XML反序列化为对象 /// </summary> /// <typeparam name="T">对象类型</typeparam> /// <param name="xml">xml字符串</param> /// <returns></returns> public static T Deserialize<T>(string xml) { XmlSerializer xmlSerializer = new XmlSerializer(typeof(T)); StringReader stringReader = new StringReader(xml); return (T)xmlSerializer.Deserialize(stringReader); } } }
XmlTypeAttribute类
该类主要控制当属性目标由XML序列化时生成的XML节点。
应用示例
/// <summary> /// Envelope /// </summary> [XmlType(TypeName = "envelope")] public class CityRes { public Header header { get; set; } public Response response { get; set; } }
XmlElementAttribute类
该类用于指示公共字段或属性在XML序列化或反序列化包含它们的对象时表示XML元素。
应用示例
/// <summary> /// Envelope /// </summary> public class CityRes { /// <summary> /// header /// </summary> [XmlElement("header")] public Header header { get; set; } /// <summary> /// response /// </summary> [XmlElement("response")] public Response response { get; set; } }
XmlAttributeAttribute类
该类指定XML序列化必须将类成员序列化为XML属性。
应用示例
/// <summary> /// Version /// </summary> public class Version { /// <summary> /// port /// </summary> [XmlAttribute("port")] public string port { get; set; } /// <summary> /// host /// </summary> [XmlAttribute("host")] public string host { get; set; } /// <summary> /// text /// </summary> [XmlAttribute("text")] public string text { get; set; } }
XmlArrayAttribute类
该类主要用于XML元素数组的应用(相当于就是集合的声明)。
应用示例
[XmlArray] public Item []Items { get{return items;} set{items = value;} }
XmlTextAttribute类
当Xml文档序列化或反序列化时使用该特性修饰的成员会作为XML文本处理。
应用示例
[System.Xml.Serialization.XmlTextAttribute()] public string[] Text { get { return this.textField; } set { this.textField = value; } }
XmlIgnoreAttribute类
指示该特性修饰的对象在Xml序列化时不会序列化该特性指定的元素。
应用示例
public class TeamGroup { [XmlIgnore] public string Comment; public string GroupName; }
用来控制XML序列化的属性汇总
通过将下表中的特性应用于类和类成员,可以控制 XmlSerializer 序列化或反序列化该类的实例的方式。 若要了解这些属性如何控制 XML 序列化,请参阅使用属性控制 XML 序列化。
特性 | 适用对象 | 指定 |
---|---|---|
XmlAnyAttributeAttribute | 公共字段、属性、参数或返回 XmlAttribute 对象数组的返回值。 | 反序列化时,将会使用 XmlAttribute 对象填充数组,而这些对象代表对于架构未知的所有 XML 特性。 |
XmlAnyElementAttribute | 公共字段、属性、参数或返回 XmlElement 对象数组的返回值。 | 反序列化时,将会使用 XmlElement 对象填充数组,而这些对象代表对于架构未知的所有 XML 元素。 |
XmlArrayAttribute | 公共字段、属性、参数或返回复杂对象的数组的返回值。 | 数组成员将作为 XML 数组的成员生成。 |
XmlArrayItemAttribute | 公共字段、属性、参数或返回复杂对象的数组的返回值。 | 可以插入数组的派生类型。 通常与 XmlArrayAttribute 一起应用。 |
XmlAttributeAttribute | 公共字段、属性、参数或返回值。 | 成员将作为 XML 属性进行序列化。 |
XmlChoiceIdentifierAttribute | 公共字段、属性、参数或返回值。 | 可以使用枚举进一步消除成员的歧义。 |
XmlElementAttribute | 公共字段、属性、参数或返回值。 | 字段或属性将作为 XML 元素进行序列化。 |
XmlEnumAttribute | 作为枚举标识符的公共字段。 | 枚举成员的元素名称。 |
XmlIgnoreAttribute | 公共属性和公共字段。 | 序列化包含类时,应该忽略属性或字段。 |
XmlIncludeAttribute | 公共派生类声明,以及 Web 服务描述语言 (WSDL) 文档的公共方法的返回值。 | 生成要在序列化时识别的架构时,应该将该类包括在内。 |
XmlRootAttribute | 公共类声明。 | 控制视为 XML 根元素的属性目标的 XML 序列化。 使用该属性可进一步指定命名空间和元素名称。 |
XmlTextAttribute | 公共属性和公共字段。 | 属性或字段应该作为 XML 文本进行序列化。 |
XmlTypeAttribute | 公共类声明。 | XML 类型的名称和命名空间。 |
参考文章
C#: .net序列化及反序列化
用来控制XML序列化的属性
使用属性控制XML序列化
微软官方文档-XML相关类汇总
到此这篇关于.NET中XML序列化和反序列化常用类和属性小结的文章就介绍到这了,更多相关.NET XML序列化和反序列化内容请搜索以前的文章或继续浏览下面的相关文章希望大家以后多多支持!
- ASP.NET下使用xml反序列化、缓存依赖实现个性化配置文件的实时生效
- asp.net xml序列化与反序列化
ASP.NET中JSON的序列化和反序列化
导读:json是专门为浏览器中的网页上运行的javascript的代码而设计的一种数据格式在网站应用中使用json的场景越来越多,本文介绍asp.net中json的序列化和反序列化,主要对json的简单介绍,asp.net如何序列化和反序列化的处理,在序列化和反序列化对日期时间,集合,字典的处理。
一,JSON简介
JSON(JavaScript对象符号,JavaScript的对象表示法)是一种轻量级的数据交换格式。
JSON是“名值对”的集合结构由大括号“{}”中括号“[]”,逗号“,”,冒号。“:”双引号''“,”''组成,包含的数据类型有对象,数字,布尔值,字符串数组,NULL等。
JSON具有以下的形式:
对象(对象)是一个无序的“名值对”集合,一个对象以“{”开始,“}”结束每个“名”后跟着一个“:”,多个“名值对”由逗号分隔如:
VAR用户= {“名”:“张三”,“性别”:“男”,“生日”:“1980年8月8日”}
数组(阵列)是值的有序集合,一个数组以“[”开始,以“]”结束,值之间使用“,”分隔如:
VAR用户列表= [{“用户”:{“名”:“张三”,“性别”:“男”,“生日”:“1980年8月8日”}},{“用户”:{“名” “李四”,“性别”:“男”,“生日”:“1985年5月8日”}}];
字符串(字符串)是由双引号包围的任意数量的的Unicode字符的集合,使用反斜线转义。
二,对JSON数据进行序列化和反序列化
可以使用DataContractJsonSerializer类将类型实例序列化为JSON字符串,并将JSON字符串反序列化为类型实例。DataContractJsonSerializer在System.Runtime.Serialization.Json命名空间下,.NET Framework 3.5的包含在System.ServiceModel.Web .dll文件中,需要添加对其的引用; .NET框架4在System.Runtime.Serialization中。
利用DataContractJsonSerializer序列化和反序列化的代码:
1:使用系统;
2:使用System.Collections.Generic;
3:使用System.Linq的;
4:使用的System.Web;
5:使用System.Runtime.Serialization.Json;
6:使用System.IO;
7:使用System.Text;
8:
9:///
10:/// JSON序列化和反序列化辅助类
11:/// 摘要>
12:公共类JsonHelper
13:{
14:///
15:/// JSON序列化
16:/// 摘要>
17:公共静态字符串JsonSerializer
18:{
19:DataContractJsonSerializer SER =新DataContractJsonSerializer(typeof运算(T));
20:MemoryStream的毫秒=新的MemoryStream();
21:ser.WriteObject(MS,T);
22:字符串jsonString = Encoding.UTF8.GetString(ms.ToArray());
23:ms.Close();
24:返回jsonString;
25:}
26:
27:///
28:/// JSON反序列化
29:/// 摘要>
30:公共静态牛逼JsonDeserialize
31:{
32:DataContractJsonSerializer SER =新DataContractJsonSerializer(typeof运算(T));
33:MemoryStream的毫秒=新的MemoryStream(Encoding.UTF8.GetBytes(jsonString));
34:T已OBJ =(T)ser.ReadObject(MS);
35:返回OBJ;
36:}
37:}
序列化演示:
简单对象的人:
1:公共类Person
2:{
3:公共字符串名称{; 组; }
4:公众诠释年龄{搞定; 组; }
5:}
序列化为JSON字符串:
1:保护无效的Page_Load(对象发件人,EventArgs的发送)
2:{
3:人p =新的Person();
4:p.Name =“张三”;
5:p.Age = 28;
6:
7:字符串jsonString = JsonHelper.JsonSerializer (P);
8:回复于(jsonString);
9:}
输出结果:
{“时代”:28日,“名”:“张三”}
反序列化演示:
1:保护无效的Page_Load(对象发件人,EventArgs的发送)
2:{
3:字符串jsonString =“{\”年龄\“:28日,\”名称\“:\”张三\“}”;
4人P = JsonHelper.JsonDeserialize (jsonString);
5:}
运行结果:
ASP.NET中的JSON序列化和反序列化还可以使用的JavaScriptSerializer,在System.Web.Script.Serializatioin命名空间下,需引用System.Web.Extensions.dll。也可以使用JSON.NET。
三,JSON序列化和反序列化日期时间的处理
JSON格式不直接支持日期和时间.DateTime值值显示为“/日期(700000 + 0500)/”形式的JSON字符串,其中第一个数字(在提供的示例中为700000)是GMT时区中自1970年1月1日午夜以来按正常时间(非夏令时)经过的毫秒数。该数字可以是负数,以表示之前的时间。示例中包括“0500”的部分可选,它指示该时间属于当地类型,即它在反序列化时应转换为本地时区。如果没有该部分,则会将时间反序列化为UTC。
修改个人类,添加LastLoginTime:
1:公共类Person
2:{
3:公共字符串名称{; 组; }
4:公众诠释年龄{搞定; 组; }
5:公共的DateTime LastLoginTime {搞定; 组; }
6:}
1:人p =新的Person();
2:p.Name =“张三”;
3:p.Age = 28;
4:p.LastLoginTime = DateTime.Now;
5:
6:字符串jsonString = JsonHelper.JsonSerializer (P);
序列化结果:
{“时代”:28日,“LastLoginTime”:“\ /日期(1294499956278 + 0800)\ /”,“姓名”:“张三”}
1.在后台使用正则表达式对其替换处理修改JsonHelper:
1:使用系统;
2:使用System.Collections.Generic;
3:使用System.Linq的;
4:使用的System.Web;
5:使用System.Runtime.Serialization.Json;
6:使用System.IO;
7:使用System.Text;
8:使用System.Text.RegularExpressions;
9:
10:///
11:/// JSON序列化和反序列化辅助类
12:/// 摘要>
13:公共类JsonHelper
14:{
15:///
16:/// JSON序列化
17:/// 摘要>
18:公共静态字符串JsonSerializer
19:{
20:DataContractJsonSerializer SER =新DataContractJsonSerializer(typeof运算(T));
21:MemoryStream的毫秒=新的MemoryStream();
22:ser.WriteObject(MS,T);
23:字符串jsonString = Encoding.UTF8.GetString(ms.ToArray());
24:ms.Close();
25://替换的Json的日期字符串
26:串P = @“ \\ /日期\((\ D +)\ + \ D + \)\\ / ”;
27:MatchEvaluator matchEvaluator =新MatchEvaluator(ConvertJsonDateToDateString);
28:正则表达式章=新的正则表达式(P);
29:jsonString = reg.Replace(jsonString,matchEvaluator);
30:返回jsonString;
31:}
32:
33:///
34:/// JSON反序列化
35:/// 摘要>
36:公共静态牛逼JsonDeserialize
37:{
38://将“YYYY-MM-DD HH:MM:SS”格式的字符串转为“\ /日期(1294499956278 + 0800)\ /”格式
39:串P = @“\ D {4} - \ d {2} - \ d {2} \ S \ D {2}:\ D {2}:\ D {2}”;
40:MatchEvaluator matchEvaluator =新MatchEvaluator(ConvertDateStringToJsonDate);
41:正则表达式章=新的正则表达式(P);
42:jsonString = reg.Replace(jsonString,matchEvaluator);
43:DataContractJsonSerializer SER =新DataContractJsonSerializer(typeof运算(T));
44:MemoryStream的毫秒=新的MemoryStream(Encoding.UTF8.GetBytes(jsonString));
45:T已OBJ =(T)ser.ReadObject(MS);
46:返回OBJ;
47:}
48:
49:///
50:///将Json的序列化的时间由/日期(1294499956278 + 0800)转为字符串
51:/// 摘要>
52:私人静态字符串ConvertJsonDateToDateString(赛米)
53:{
54:字符串结果=的String.Empty;
55:DateTime的DT =新日期时间(1970,1,1);
56:DT = dt.AddMilliseconds(long.Parse(m.Groups [1] .value的));
57:DT = dt.ToLocalTime();
58:结果= dt.ToString(“YYYY-MM-DD HH:MM:SS”);
59:返回结果;
60:}
61:
62:///
63:///将时间字符串转为Json的时间
64:/// 摘要>
65:私人静态字符串ConvertDateStringToJsonDate(赛米)
66:{
67:字符串结果=的String.Empty;
68:DateTime的DT = DateTime.Parse(m.Groups [0] .value的);
69:DT = dt.ToUniversalTime();
70:时间跨度TS = DT - DateTime.Parse(“1970-01-01”);
71:结果=的String.Format(“ \\ /日期({0} +0800)\\ /”,ts.TotalMilliseconds);
72:返回结果;
73:}
74:}
序列化演示:
1:人p =新的Person();
2:p.Name =“张三”;
3:p.Age = 28;
4:p.LastLoginTime = DateTime.Now;
5:
6:字符串jsonString = JsonHelper.JsonSerializer (P);
运行结果:
{“时代”:28日,“LastLoginTime”:“2011-01-09一点○○分56秒”,“姓名”:“张三”}
反序列化演示:
JSON字符串=“{\”年龄\“:28日,\”LastLoginTime \“:\”2011-01-09 00:30:00 \“,\”名称\“:\”张三\“}”;
P = JsonHelper.JsonDeserialize (JSON);
运行结果:
在后台替换字符串适用范围比较窄,如果考虑到全球化的有多种语言还会更麻烦。
2.利用JavaScript的处理
1:功能ChangeDateFormat(jsondate){
2:jsondate = jsondate.replace(“/日期(”,“”).replace(“)/”,“”);
3:如果(jsondate.indexOf(“+”)> 0){
4:jsondate = jsondate.substring(0,jsondate.indexOf(“+”));
5:}
6:否则如果(jsondate.indexOf(“ - ”)> 0){
7:jsondate = jsondate.substring(0,jsondate.indexOf(“ - ”));
8:}
9:
10:VAR日期=新的日期(parseInt函数(jsondate,10));
11:无功一个月= date.getMonth()+ 1
12:VAR的currentdate = date.getDate()
13:返回date.getFullYear()+“ - ”+月+“ - ”+的currentdate;
14:}
简单演示:
ChangeDateFormat(“\ /日期(1294499956278 + 0800)\ /”);
结果:
四,JSON序列化和反序列化集合,字典,数组的处理
在JSON数据中,所有的集合,字典和数组都表示为数组。
名单
1:名单列表=新的List ()
2:{
3:新的Person(){名称=“张三”,年龄= 28},
4:新的Person(){名称=“李四”,年龄= 25}
5:};
6:
7:字符串jsonString = JsonHelper.JsonSerializer >(名单);
序列化结果:
“[{\”年龄\“:28日,\”名称\“:\”张三\“},{\”年龄\“:25,\”名称\“:\”李四\“}]”
字典不能直接用于JSON,字典字典转化为JSON并不是跟原来的字典格式一致,而是形式以词典的按键作为名称“密钥”的值,以字典的值作为名称为“值”的值。如:
1:词典 DIC =新词典();
2:dic.Add(“姓名”,“张三”);
3:dic.Add(“时代”,“28”);
4:
5:字符串jsonString = JsonHelper.JsonSerializer >(DIC);
序列化结果:
1:“[{\”键\“:\”名称\“,\”价值\“:\”张三\“},{\”键\“:\”年龄\“,\”价值\“: \“28 \”}]“
今天的关于在Json.Net中序列化属性,但不要反序列化属性和net json序列化的分享已经结束,谢谢您的关注,如果想了解更多关于.NET中JSON数据进行序列化和反序列化操作分析、.NET中JSON的序列化和反序列化的几种方式、.NET中XML序列化和反序列化常用类和属性小结、ASP.NET中JSON的序列化和反序列化的相关知识,请在本站进行查询。
本文将分享使用 imageEdgeInsets 和 titleEdgeInsets 对齐 UIButton 上的文本和图像的详细内容,此外,我们还将为大家带来关于Android Studio:尝试在空对象引用上调用虚拟方法“void android.widget.ImageButton.setImageResource(int)”、android.support.design.widget.CheckableImageButton的实例源码、Android:在 Button 或 ImageButton 上组合文本和图像、Android:在Button或ImageButton上组合文本和图像的相关知识,希望对你有所帮助。
本文目录一览:- 使用 imageEdgeInsets 和 titleEdgeInsets 对齐 UIButton 上的文本和图像
- Android Studio:尝试在空对象引用上调用虚拟方法“void android.widget.ImageButton.setImageResource(int)”
- android.support.design.widget.CheckableImageButton的实例源码
- Android:在 Button 或 ImageButton 上组合文本和图像
- Android:在Button或ImageButton上组合文本和图像
使用 imageEdgeInsets 和 titleEdgeInsets 对齐 UIButton 上的文本和图像
我想在两行文本的左侧放置一个图标,使图像和文本开头之间有大约 2-3 像素的空间。控件本身水平居中对齐(通过 Interface Builder 设置)
该按钮将类似于以下内容:
| ||[Image] Add To || Favorites |
我正在尝试使用 contentEdgeInset、imageEdgeInsets 和 titleEdgeInsets
进行配置,但无济于事。我知道负值会扩大边缘,而正值会缩小边缘以使其更靠近中心。
我试过:
[button setTitleEdgeInsets:UIEdgeInsetsMake(0, -image.size.width, 0, 0)];[button setImageEdgeInsets:UIEdgeInsetsMake(0, button.titleLabel.bounds.size.width, 0, 0)];
但这不能正确显示。我一直在调整这些值,但是从左侧插入值的 -5 到 -10 似乎并没有以预期的方式移动它。-10 会将文本一直向左移动,所以我希望 -5
将它从左侧移动到一半,但事实并非如此。
插图背后的逻辑是什么?我不熟悉图像放置和相关术语。
答案1
小编典典我同意文档imageEdgeInsets
并且titleEdgeInsets
应该更好,但我想出了如何在不诉诸试验和错误的情况下获得正确的定位。
一般的想法是在这个问题上,但那是如果你想要文本和图像都居中。我们不希望图像和文本单独居中,我们希望图像和文本作为一个实体一起居中。这实际上是
UIButton 已经做的,所以我们只需要调整间距。
CGFloat spacing = 10; // the amount of spacing to appear between image and titletabBtn.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing);tabBtn.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);
我还把它变成了 UIButton 的一个类别,所以它很容易使用:
UIButton+Position.h
@interface UIButton(ImageTitleCentering)-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing;@end
UIButton+位置.m
@implementation UIButton(ImageTitleCentering)-(void) centerButtonAndImageWithSpacing:(CGFloat)spacing { self.imageEdgeInsets = UIEdgeInsetsMake(0, 0, 0, spacing); self.titleEdgeInsets = UIEdgeInsetsMake(0, spacing, 0, 0);}@end
所以现在我要做的就是:
[button centerButtonAndImageWithSpacing:10];
我每次都能得到我需要的东西。不再手动弄乱边缘插图。
编辑:交换图像和文本
在评论中回复@Javal
使用相同的机制,我们可以交换图像和文本。要完成交换,只需使用负间距,但还要包括文本和图像的宽度。这将需要已知框架并且已经执行布局。
[self.view layoutIfNeeded];CGFloat flippedSpacing = -(desiredSpacing + button.currentImage.size.width + button.titleLabel.frame.size.width);[button centerButtonAndImageWithSpacing:flippedSpacing];
当然,您可能想要为此创建一个不错的方法,可能会添加第二类方法,这留给读者作为练习。
Android Studio:尝试在空对象引用上调用虚拟方法“void android.widget.ImageButton.setImageResource(int)”
您的 post_item.xml 文件是否附加到 Recycler 视图?如果是,则必须使用点击侦听器。
,只需从 recyclerAdapter.java
android.support.design.widget.CheckableImageButton的实例源码
/** Returns a matcher that matches TextInputLayouts with non-displayed password toggles */ public static Matcher<View> passwordToggleIsNotChecked() { return new TypeSafeMatcher<View>(TextInputLayout.class) { @Override public void describeto(Description description) { description.appendText("TextInputLayout has checked password toggle."); } @Override protected boolean matchesSafely(View item) { // Reach in and find the password toggle since we don't have a public API // to get a reference to it CheckableImageButton passwordToggle = item.findViewById(R.id.text_input_password_toggle); return !passwordToggle.isChecked(); } }; }
public void setupUI(View view) { // Set up touch listener for non-text Box views to hide keyboard. // We should also ignore "show password" icon if (!(view instanceof EditText) && !(view instanceof CheckableImageButton)) { view.setonTouchListener((v,event) -> { hideKeyboard(); return false; }); } //If a layout container,iterate over children and seed recursion. if (view instanceof ViewGroup) { for (int i = 0; i < ((ViewGroup) view).getChildCount(); i++) { View innerView = ((ViewGroup) view).getChildAt(i); setupUI(innerView); } } }
@Override public void onViewCreated(View view,@Nullable Bundle savedInstanceState) { viewBaseMapButton = (CheckableImageButton) view.findViewById(R.id.view_base_map_button); viewBaseMapButton.setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { modeWithBaseMap = !modeWithBaseMap; showMapImage(modeWithBaseMap); } }); showMapImage(modeWithBaseMap); }
private IInterpretationViewHolder onCreateContentViewHolder(ViewGroup parent,int viewType) { switch (viewType) { case ITEM_WITH_IMAGE_TYPE: { View rootView = getLayoutInflater().inflate( R.layout.recycler_view_dashboard_item_imageview,parent,false); ImageView imageView = (ImageView) rootView.findViewById(R.id.dashboard_item_image); CheckableImageButton modeButton = (CheckableImageButton) rootView.findViewById(R.id.view_mode_button); return new ImageItemViewHolder(rootView,modeButton,imageView,mClickListener); } case ITEM_WITH_TABLE_TYPE: { TextView textView = (TextView) getLayoutInflater() .inflate(R.layout.recycler_view_dashboard_item_textview,false); return new TextItemViewHolder(textView,mClickListener); } } return null; }
public ImageItemViewHolder(View rootView,CheckableImageButton modeButton,ImageView view,OnItemClickListener outerListener) { this.rootView = rootView; this.imageView = view; this.modeButton = modeButton; mImageLoader = PicassoProvider.getInstance(rootView.getContext(),false); listener = new OnInterpretationInternalClickListener(outerListener); imageView.setonClickListener(listener); modeButton.setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { modeWithBaseMap = !modeWithBaseMap; showMapImage(modeWithBaseMap); } }); }
public ImageItemViewHolder(View rootView,false); listener = new OnElementInternalClickListener(outerListener); imageView.setonClickListener(listener); modeButton.setonClickListener(new View.OnClickListener() { @Override public void onClick(View v) { modeWithBaseMap = !modeWithBaseMap; showMapImage(modeWithBaseMap); } }); }
/** * Depending on viewType,this method will return correct IElementContentViewHolder. * * * @param rootView * @param parent Parent ViewGroup. * @param viewType Type of view we want to get IElementContentViewHolder for. * @return view holder. */ private IElementContentViewHolder onCreateElementContentViewHolder( ViewGroup parent,mClickListener); } case ITEM_WITH_LIST_TYPE: { LinearLayout textViewContainer = (LinearLayout) getLayoutInflater() .inflate(R.layout.recycler_view_dashboard_item_list,false); return new ListItemViewHolder(textViewContainer,mClickListener,mDashboardAccess); } } return null; }
public CheckableImageButton getpasswordToggleView() { return mPasswordToggleView; }
public CheckableImageButton getpasswordToggleView() { return mPasswordToggleView; }
public CheckableImageButton getpasswordToggleView() { return mPasswordToggleView; }
public CheckableImageButton getpasswordToggleView() { return mPasswordToggleView; }
Android:在 Button 或 ImageButton 上组合文本和图像
我正在尝试在按钮上添加图像(作为背景)并根据运行时发生的情况动态添加图像上方/上方的一些文本。
如果我使用ImageButton
,我什至无法添加文本。如果我使用Button
,我可以添加文本,但只定义具有此处android:drawableBottom
定义的类似
XML
属性的图像。
然而,这些属性只结合了 x 和 y 维度的文本和图像,这意味着我可以在文本周围绘制图像,但不能在文本下方/下方(z 轴定义为从显示器中出来)。
关于如何做到这一点的任何建议?一个想法是扩展Button
或ImageButton
覆盖draw()
-
方法。但是以我目前的知识水平,我真的不知道如何做到这一点(2D 渲染)。也许有更多经验的人知道解决方案或至少有一些开始的指示?
答案1
小编典典您可以调用setBackground()
aButton
来设置按钮的背景。
任何文本都将出现在背景之上。
如果您在 xml 中寻找类似的东西,则有: android:background
以相同方式工作的属性。
Android:在Button或ImageButton上组合文本和图像
我正在尝试在按钮上创建一个图像(作为背景)并动态添加,具体取决于运行时发生的情况,图像上方/上方的一些文本。
如果我使用ImageButton
我甚至无法添加文本。 如果我使用Button
我可以添加文本,但只定义一个带有android:drawableBottom
的图像和此处定义的类似XML属性。
然而,这些属性仅在x和y维度中组合文本和图像,这意味着我可以在文本周围绘制图像,但不能在文本的下方/下方(z轴定义为从显示中出来)。
有关如何做到这一点的任何建议? 一个想法是扩展Button
或ImageButton
并覆盖draw()
- 方法。 但凭借我目前的知识水平,我真的不知道如何做到这一点(2D渲染)。 也许有经验的人知道解决方案或至少有一些指针可以开始?
#1楼
您可以在Button
上调用setBackground()
来设置Button
的背景。
任何文本都将显示在背景上方。
如果你在xml中寻找类似的东西,那么: android:background
属性的工作方式相同。
#2楼
<Button
android:id="@+id/groups_button_bg"
android:layout_height="wrap_content"
android:layout_width="wrap_content"
android:text="Groups"
android:drawableTop="@drawable/[image]" />
android:drawableLeft
android:drawableRight
android:drawableBottom
android:drawableTop
http://www.mokasocial.com/2010/04/create-a-button-with-an-image-and-text-android/
#3楼
你可以用这个:
<Button
android:id="@+id/reset_all"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginRight="5dp"
android:layout_weight="1"
android:background="@drawable/btn_med"
android:text="Reset all"
android:textColor="#ffffff" />
<Button
android:id="@+id/undo"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginLeft="5dp"
android:layout_weight="1"
android:background="@drawable/btn_med"
android:text="Undo"
android:textColor="#ffffff" />
因为我把图像作为background
,并添加了文字..!
#4楼
您可以使用drawableTop
(也是drawableLeft
等)为图像添加gravity
left|center_vertical
<Button
android:id="@+id/btn_video"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentRight="true"
android:layout_centerVertical="true"
android:background="@null"
android:drawableTop="@drawable/videos"
android:gravity="left|center_vertical"
android:onClick="onClickFragment"
android:text="Videos"
android:textColor="@color/white" />
#5楼
这段代码非常适合我
<LinearLayout
android:id="@+id/choosePhotosView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:orientation="horizontal"
android:gravity="center"
android:clickable="true"
android:background="@drawable/transparent_button_bg_rev_selector">
<ImageView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:src="@drawable/choose_photo"/>
<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textColor="@android:color/white"
android:text="@string/choose_photos_tv"/>
</LinearLayout>
今天关于使用 imageEdgeInsets 和 titleEdgeInsets 对齐 UIButton 上的文本和图像的分享就到这里,希望大家有所收获,若想了解更多关于Android Studio:尝试在空对象引用上调用虚拟方法“void android.widget.ImageButton.setImageResource(int)”、android.support.design.widget.CheckableImageButton的实例源码、Android:在 Button 或 ImageButton 上组合文本和图像、Android:在Button或ImageButton上组合文本和图像等相关知识,可以在本站进行查询。
最近很多小伙伴都在问ConcurrentHashMap和Collections.synchronizedMap和Map有什么区别?这两个问题,那么本篇文章就来给大家详细解答一下,同时本文还将给你拓展Collectors.toConcurrentMap和通过Collectors.toMap供应商选项将地图转换为ConcurrentHashMap有什么区别?、com.google.common.collect.Synchronized.SynchronizedBiMap的实例源码、com.google.common.collect.Synchronized.SynchronizedNavigableMap的实例源码、com.google.common.collect.Synchronized.SynchronizedSortedMap的实例源码等相关知识,下面开始了哦!
本文目录一览:- ConcurrentHashMap和Collections.synchronizedMap(Map)有什么区别?(concurrenthashmap的区别)
- Collectors.toConcurrentMap和通过Collectors.toMap供应商选项将地图转换为ConcurrentHashMap有什么区别?
- com.google.common.collect.Synchronized.SynchronizedBiMap的实例源码
- com.google.common.collect.Synchronized.SynchronizedNavigableMap的实例源码
- com.google.common.collect.Synchronized.SynchronizedSortedMap的实例源码
ConcurrentHashMap和Collections.synchronizedMap(Map)有什么区别?(concurrenthashmap的区别)
我有一个地图,该地图将同时被多个线程修改。
Java API中似乎有三种不同的同步Map实现:
- Hashtable
- Collections.synchronizedMap(Map)
- ConcurrentHashMap
据我了解,这Hashtable
是一个旧的实现(扩展了过时的Dictionary
类),后来对其进行了修改以适合该Map接口。虽然它是同步的,但似乎存在严重的可伸缩性问题,因此不建议用于新项目。
但是其他两个呢?Collections.synchronizedMap(Map)
和ConcurrentHashMaps
返回的Map之间有什么区别?哪一种适合哪种情况?
答案1
小编典典为您的需要使用ConcurrentHashMap
。它允许从多个线程并发修改Map,而无需阻止它们。Collections.synchronizedMap(map)
创建一个阻塞映射,这会降低性能,尽管会确保一致性(如果使用正确)。
如果需要确保数据一致性,并且每个线程都需要具有最新的地图视图,请使用第二个选项。如果性能至关重要,请使用第一个,并且每个线程仅将数据插入到映射中,而读取的频率则较低。
答案2
小编典典╔═══════════════╦═══════════════════╦═══════════════════╦═════════════════════╗║ Property ║ HashMap ║ Hashtable ║ ConcurrentHashMap ║╠═══════════════╬═══════════════════╬═══════════════════╩═════════════════════╣ ║ Null ║ allowed ║ not allowed ║║ values/keys ║ ║ ║╠═══════════════╬═══════════════════╬═════════════════════════════════════════╣║ Thread-safety ║ ║ ║║ features ║ no ║ yes ║╠═══════════════╬═══════════════════╬═══════════════════╦═════════════════════╣║ Lock ║ not ║ locks the whole ║ locks the portion ║ ║ mechanism ║ applicable ║ map ║ ║ ╠═══════════════╬═══════════════════╩═══════════════════╬═════════════════════╣║ Iterator ║ fail-fast ║ weakly consistent ║ ╚═══════════════╩═══════════════════════════════════════╩═════════════════════╝
关于锁定机制: Hashtable
锁定对象,而仅ConcurrentHashMap
锁定存储桶。
Collectors.toConcurrentMap和通过Collectors.toMap供应商选项将地图转换为ConcurrentHashMap有什么区别?
我想通过Java 8 和接口将a Map
转换为ConcurrentHashMap
via ,我可以使用两个选项。Stream``Collector
首先:
Map<Integer, String> mb = persons.stream() .collect(Collectors.toMap( p -> p.age, p -> p.name, (name1, name2) -> name1+";"+name2, ConcurrentHashMap::new));
第二个:
Map<Integer, String> mb1 = persons.stream() .collect(Collectors.toConcurrentMap( p -> p.age, p -> p.name));
哪个是更好的选择?什么时候应该使用每个选项?
答案1
小编典典在处理并行流时,它们之间是有区别的。
toMap
->是非并行收集器
toConcurrentMap
->是并发收集器(这可以从它们的特征中看出)。
区别在于 toMap 将创建多个中间结果,然后将其合并在一起(多次调用该Collector的Supplier),而 toConcurrentMap
将创建 单个 结果,并且每个Thread都会向其抛出结果(此类的Supplier收藏家只会被调用一次)
为什么这很重要?这处理插入顺序(如果有的话)。
toMap 将通过合并多个中间结果按遇到的顺序在结果Map中插入值(该收集器的供应商称为“多次”,也称为“合并器”)
toConcurrentMap
将通过将所有元素扔到公共结果容器(在这种情况下为ConcurrentHashMap)来以任何顺序(未定义)收集元素。供应商仅被调用一次,累加器被调用多次,而合并器则从未被调用。
这里的一个小警告是CONCURRENT
收集器不调用合并:流必须具有UNORDERED
标志-
通过unordered()
显式调用或当流的源未排序时(Set
例如)。
com.google.common.collect.Synchronized.SynchronizedBiMap的实例源码
public void testInverse() { BiMap<String,Integer> bimap = create(); BiMap<Integer,String> inverse = bimap.inverse(); assertSame(bimap,inverse.inverse()); assertTrue(inverse instanceof SynchronizedBiMap); assertSame(mutex,((SynchronizedBiMap<?,?>) inverse).mutex); }
public void testInverse() { BiMap<String,?>) inverse).mutex); }
public void testInverse() { BiMap<String,?>) inverse).mutex); }
public void testInverse() { BiMap<String,?>) inverse).mutex); }
com.google.common.collect.Synchronized.SynchronizedNavigableMap的实例源码
public void testDescendingMap() { NavigableMap<String,Integer> map = create(); NavigableMap<String,Integer> descendingMap = map.descendingMap(); assertTrue(descendingMap instanceof SynchronizednavigableMap); assertSame(mutex,((SynchronizednavigableMap<String,Integer>) descendingMap).mutex); }
public void testHeadMap_K_B() { NavigableMap<String,Integer> headMap = map.headMap("a",true); assertTrue(headMap instanceof SynchronizednavigableMap); assertSame( mutex,Integer>) headMap).mutex); }
public void testSubMap_K_B_K_B() { NavigableMap<String,Integer> subMap = map.subMap("a",true,"b",false); assertTrue(subMap instanceof SynchronizednavigableMap); assertSame( mutex,Integer>) subMap).mutex); }
public void testTailMap_K_B() { NavigableMap<String,Integer> subMap = map.tailMap("a",true); assertTrue(subMap instanceof SynchronizednavigableMap); assertSame( mutex,Integer>) subMap).mutex); }
public void testDescendingMap() { NavigableMap<String,Integer>) descendingMap).mutex); }
public void testHeadMap_K_B() { NavigableMap<String,Integer>) headMap).mutex); }
public void testSubMap_K_B_K_B() { NavigableMap<String,Integer>) subMap).mutex); }
public void testTailMap_K_B() { NavigableMap<String,Integer>) subMap).mutex); }
public void testDescendingMap() { NavigableMap<String,Integer>) descendingMap).mutex); }
public void testHeadMap_K_B() { NavigableMap<String,Integer>) headMap).mutex); }
public void testSubMap_K_B_K_B() { NavigableMap<String,Integer>) subMap).mutex); }
public void testTailMap_K_B() { NavigableMap<String,Integer>) subMap).mutex); }
public void testDescendingMap() { NavigableMap<String,Integer>) descendingMap).mutex); }
public void testHeadMap_K_B() { NavigableMap<String,true); assertTrue(headMap instanceof SynchronizednavigableMap); assertSame(mutex,Integer>) headMap).mutex); }
public void testSubMap_K_B_K_B() { NavigableMap<String,false); assertTrue(subMap instanceof SynchronizednavigableMap); assertSame(mutex,Integer>) subMap).mutex); }
public void testTailMap_K_B() { NavigableMap<String,true); assertTrue(subMap instanceof SynchronizednavigableMap); assertSame(mutex,Integer>) subMap).mutex); }
com.google.common.collect.Synchronized.SynchronizedSortedMap的实例源码
public void testHeadMap_K() { NavigableMap<String,Integer> map = create(); SortedMap<String,Integer> headMap = map.headMap("a"); assertTrue(headMap instanceof SynchronizedSortedMap); assertSame(mutex,((SynchronizedSortedMap<String,Integer>) headMap).mutex); }
public void testSubMap_K_K() { NavigableMap<String,Integer> subMap = map.subMap("a","b"); assertTrue(subMap instanceof SynchronizedSortedMap); assertSame(mutex,Integer>) subMap).mutex); }
public void testTailMap_K() { NavigableMap<String,Integer> subMap = map.tailMap("a"); assertTrue(subMap instanceof SynchronizedSortedMap); assertSame(mutex,Integer>) subMap).mutex); }
public void testHeadMap_K() { NavigableMap<String,Integer>) headMap).mutex); }
public void testSubMap_K_K() { NavigableMap<String,Integer>) subMap).mutex); }
public void testTailMap_K() { NavigableMap<String,Integer>) subMap).mutex); }
public void testHeadMap_K() { NavigableMap<String,Integer>) headMap).mutex); }
public void testSubMap_K_K() { NavigableMap<String,Integer>) subMap).mutex); }
public void testTailMap_K() { NavigableMap<String,Integer>) subMap).mutex); }
public void testHeadMap_K() { NavigableMap<String,Integer>) headMap).mutex); }
public void testSubMap_K_K() { NavigableMap<String,Integer>) subMap).mutex); }
public void testTailMap_K() { NavigableMap<String,Integer>) subMap).mutex); }
今天关于ConcurrentHashMap和Collections.synchronizedMap和Map有什么区别?的讲解已经结束,谢谢您的阅读,如果想了解更多关于Collectors.toConcurrentMap和通过Collectors.toMap供应商选项将地图转换为ConcurrentHashMap有什么区别?、com.google.common.collect.Synchronized.SynchronizedBiMap的实例源码、com.google.common.collect.Synchronized.SynchronizedNavigableMap的实例源码、com.google.common.collect.Synchronized.SynchronizedSortedMap的实例源码的相关知识,请在本站搜索。
针对在python中格式化“昨天的”日期和python 昨天日期这两个问题,本篇文章进行了详细的解答,同时本文还将给你拓展Python – 以YYYY-MM-DD格式的字符串获取昨天的日期、python – 如何在PyCharm中格式化多行TODO注释?、Python 昨天的日期、python中日期和时间格式化输出的方法小结_python等相关知识,希望可以帮助到你。
本文目录一览:- 在python中格式化“昨天的”日期(python 昨天日期)
- Python – 以YYYY-MM-DD格式的字符串获取昨天的日期
- python – 如何在PyCharm中格式化多行TODO注释?
- Python 昨天的日期
- python中日期和时间格式化输出的方法小结_python
在python中格式化“昨天的”日期(python 昨天日期)
我需要MMDDYY
在 Python 中以这种格式查找“昨天的”日期。
例如,今天的日期将表示为:111009
我今天可以很容易地做到这一点,但我在“昨天”自动做到这一点时遇到了麻烦。
答案1
小编典典采用datetime.timedelta()
>>> from datetime import date, timedelta>>> yesterday = date.today() - timedelta(days=1)>>> yesterday.strftime(''%m%d%y'')''110909''
Python – 以YYYY-MM-DD格式的字符串获取昨天的日期
yesterday = datetime.date.fromordinal(datetime.date.today().toordinal()-1) report_date = str(yesterday.year) + \ ('-' if len(str(yesterday.month)) == 2 else '-0') + str(yesterday.month) + \ ('-' if len(str(yesterday.day)) == 2 else '-0') + str(yesterday.day)
必须有一个更优雅的方式来做到这一点,感兴趣的是教育目的和其他任何事情一样!
解决方法
timedelta
object,这是一天的持续时间,并且可以从datetime对象中减去.然后,您可以使用
datetime.strftime
在orer中将日期对象转换为基于
espected format的字符串:
>>> from datetime import datetime,timedelta >>> datetime.strftime(datetime.Now() - timedelta(1),'%Y-%m-%d') '2015-05-26'
请注意,不用调用datetime.strftime函数,也可以直接使用datetime对象的strftime方法:
>>> (datetime.Now() - timedelta(1)).strftime('%Y-%m-%d') '2015-05-26'
python – 如何在PyCharm中格式化多行TODO注释?
# Todo: Multiple errors can be wrapped inside an exception. # WfcApiException should do recursive error checking to locate # and store an arbitrary number of nested errors.
不幸的是,PyCharm只将第一行识别为Todo评论.以下任何行都被视为标准Python注释.
在PyCharm中格式化多行Todo注释的正确方法是什么?
解决方法
PyCharm does not支持多行Todo,另一种选择是使用多行字符串
''' Todo foobar foobar '''
这将不会像#Todo foo那样突出显示Todo,但它会突出显示字符串突出显示的其余代码.
你也可以试试
# Todo ----------------- # Todo foobar this # Todo comment # Todo comment # Todo comment # Todo ------------------
如果你有一个特别厚实和重要的Todo笔记.
Python 昨天的日期
import datetime def getYesterday(): today = datetime.date.today() oneDay = datetime.timedelta(days=1) yesterday = today - oneDay return yesterday print(getYesterday())
python中日期和时间格式化输出的方法小结_python
这篇文章主要介绍了
本文实例总结了python中日期和时间格式化输出的方法。分享给大家供大家参考。具体分析如下:
python格式化日期时间的函数为datetime.datetime.strftime();由字符串转为日期型的函数为:datetime.datetime.strptime(),两个函数都涉及日期时间的格式化字符串,这里提供详细的代码详细演示了每一个参数的使用方法及范例。
下面是格式化日期和时间时可用的替换符号 %a 输出当前是星期几的英文简写
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%a') 'Sun'
%A 输出完整的星期几名称英文
立即学习“Python免费学习笔记(深入)”;
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%A') 'Sunday'
%b 输出月份的英文简写
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%b') 'Sep'
%B 输出月份的英文完整名称
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%B') 'September'
%c 以本地时间显示日期和时间
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%c') '09/15/13 21:43:29'
%d 显示1-31之间的数,每月的第几天,也就是年月日中的日
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%d') '15'
%H 以24小时制显示小时,比如,02,14
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%H') '21'
%I 以12小时制的方式显示当前小时,例如当前jb51.net服务器的时间为晚上21点,使用%I显示09
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%I') '09'
%j 显示当前日期为一年中的第几天,如当前jb51.net服务器时间为2013年9月15日,则显示为258,也就是一年中的第258天
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%j') '258'
%m 显示1-12之间的月份
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%m') '09'
%M 显示00-59之间的分钟数
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%M') '43'
%p 以 A.M./P.M.方式显示是上午还是下午
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%p') 'PM'
%S 显示0-59之间的秒数
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%S') '29'
%U 显示一年中的第几周,星期天为一周的第一天,例如当前www.jb51.net服务器时间为2013年9月15日,星期天,显示为第37周
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%U') '37'
%w 显示一周中的第几天,其中星期天为0,星期一为1,例如:jb51.net当前日期为2013年9月17日星期二,则显示结果为2
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%w') '2'
%W 显示一年中的第几周,和U%把不同的是星期一为一周的第一天,例如当前www.jb51.net服务器时间为2013年9月17日,星期二,显示为第37周,范围在0-51之间
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%W') '37'
%x 显示当地的日期,例如jb51.net本地时间为:北京时间2013年9月17日
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%x') '09/17/13'
%X 显示当地的时间,例如jb51.net本地时间为:北京时间2013年9月17日 07:55:04
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%X') '07:55:04'
%y 显示(00 - 99) 之间的年份,例如:jb51.net服务器时间为:2013年9月17日,则显示结果为13
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%y') '13'
%Y 显示完整年份,例如:jb51.net服务器时间为:2013年9月17日,则显示结果为2013
>>> import datetime >>> now=datetime.datetime.now() >>> now.strftime('%Y') '2013'
%z, %Z 输出时区,如果不能显示,则显示为空字符 %% 用于显示%符号
>>> now.strftime('%%') '%'
在举一个完整的例子:
显示当前日期时间:格式为:年-月-日 时:分:秒
>>> datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S'); '2013-09-17 08:06:17'
以上就是
关于在python中格式化“昨天的”日期和python 昨天日期的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于Python – 以YYYY-MM-DD格式的字符串获取昨天的日期、python – 如何在PyCharm中格式化多行TODO注释?、Python 昨天的日期、python中日期和时间格式化输出的方法小结_python等相关知识的信息别忘了在本站进行查找喔。
在这里,我们将给大家分享关于如何在 MonoTouch 和 Objective-C 之间做出选择?的知识,同时也会涉及到如何更有效地c# – MonoTouch v.Objective-C for new iPhone devs、C#Constructor重载:new object.FromOtherObject()?、cannot be found on object of type xx.CacheExpressionRootObject、CRM 系统和 ERP 系统有哪些区别?企业如何在二者之间做出选择?的内容。
本文目录一览:- 如何在 MonoTouch 和 Objective-C 之间做出选择?
- c# – MonoTouch v.Objective-C for new iPhone devs
- C#Constructor重载:new object.FromOtherObject()?
- cannot be found on object of type xx.CacheExpressionRootObject
- CRM 系统和 ERP 系统有哪些区别?企业如何在二者之间做出选择?
如何在 MonoTouch 和 Objective-C 之间做出选择?
今天在当地的 .Net 活动中参加了有关 Mono 的会议后,MonoTouch 的使用被“触及”为 iPhone 开发的替代方案。在 C# 和 .Net
中非常舒服,这似乎是一个吸引人的选择,尽管 Mono 堆栈有些古怪。然而,由于 MonoTouch 的价格为 400 美元,我有点担心这是否是 iPhone
开发的方式。
任何人都有过使用 MonoTouch 和 Objective-C 开发的经验,如果有的话,使用 MonoTouch 进行开发是否比学习
Objective-C 更简单、更快捷,并且值 400 美元?
答案1
小编典典我最近经常看到这个问题(及其变体)。令我惊讶的是,人们回复的频率很高,但回复的次数却 很少 。
我有我的偏好(我喜欢这两种堆栈),但这是大多数“答案”开始出错的地方。它不应该是关于我想要什么(或其他人想要什么)。
以下是我如何确定 MonoTouch 的价值 - 显然,我不能客观,但我认为这是非常狂热的:
这是娱乐还是商务?如果你想进入这个领域的咨询,你可以很快赚回 399 美元。
你想从内到外学习这个平台,还是“只是”想为它编写应用程序?
您是否足够喜欢 .Net,以至于使用不同的开发堆栈会为您带来乐趣?同样,我喜欢这两种堆栈(Apple 和 Mono),但对我来说,MonoTouch 让体验变得更加有趣。我并没有停止使用 Apple 的工具,但这主要是因为我 真的很喜欢这两种堆栈 。我喜欢 iPhone,也喜欢 .Net。在那种情况下,对我来说,MonoTouch 是轻而易举的事。
你觉得和 C 一起工作很舒服吗?我指的不是 Objective-C,而是 C——这很重要,因为 Objective-C 是 C。它是一个不错的、花哨的、友好的 OO 版本,但是如果指针给你带来了 heebie-jeebies,那么 MonoTouch 就是你的朋友。如果碰巧您 不 喜欢指针(或 C 等),请不要听那些认为您是开发者的反对者。我过去常常带着一份 IBM ROM BIOS Pocket Reference 的副本四处走动,当我编写程序集并迫使我的计算机进入有趣的视频模式并为它们和(诚然垃圾)窗口系统编写我自己的字体渲染位时,我没有不要认为 QuickBasic 的开发者是坏蛋。我 是 一个 QuickBasic 开发人员(除了其余的)。永远不要屈服于书呆子的男子气概。如果你不喜欢 C,如果你不喜欢指针,如果你想尽可能远离手动内存管理(而且,公平地说,在 ObjC 中一点也不差),那么。 .. 单触。并且不要为此胡说八道。
您想定位用户或企业吗?对我来说这并不重要,但仍然有人在 Edge 上,事实是:如果你使用 Apple 的堆栈,你可以创建一个更小的下载包。我一直在玩 MonoTouch,我有一个不错的小应用程序,一旦压缩,它会降到大约 2.7 MB(提交你的应用程序进行分发时,你压缩它 - 当应用程序从商店下载时,他们’重新压缩 - 因此,当确定您的应用程序是否会低于 10MB OTA 限制时,请先压缩傻瓜 - MonoTouch 会让您感到惊喜)。但是,除了 MT 的快乐之外,如果您的目标是最终用户,那么半兆与近 3(例如)对您来说可能很重要。如果您正在考虑企业工作,那么几 MB 根本无关紧要。和,需要明确的是——我将很快向商店提交一个基于 MT 的应用程序,我对大小没有任何问题。根本不打扰我。但如果这是值得关注的事情 你 ,那么 Apple 的堆栈赢了这个。
做任何 XML 工作?单触。时期。
字符串操作?日期操纵?我们已经习惯使用 .Net 的一切和厨房水槽框架的其他一百万个小东西?单触。
网页服务?单触。
从语法上讲,它们都有各自的优势。 Objective-C在你必须写它的地方 往往更冗长。您会发现自己使用 C# 编写代码,而不必使用 ObjC 编写代码,但它是双向的。这个特定的主题可以写满一本书。我更喜欢 C# 语法,但在克服了我最初对 Objective-C 的“这是超凡脱俗”的反应之后,我学会了享受它。我在谈话中取笑它(这对于习惯于 C#/Java/等的开发人员来说 很 奇怪),但事实是我心里有一个 Objective-C 形状的点让我很开心。
你打算使用界面生成器吗?因为,即使在这个早期版本中,我发现自己用 IB 构建我的 UI 并在代码中使用它们的工作要少得多。感觉就像 Objective-C/IB 的做事方式缺少整个步骤,我很确定这是因为 Objective-C/IB 的做事方式缺少整个步骤。到目前为止,我认为我没有进行充分的测试,但 到目前为止 ,MonoTouch 是这里的赢家,因为你需要做的工作少得多。
你认为学习新的语言和平台很有趣吗?如果是这样,iPhone 可以提供很多东西,Apple 的堆栈可能会让你走出舒适区——这对一些开发者来说很 有趣 (嗨——我是其中的开发者之一——我开玩笑说Apple 经历了一段艰难时期,但我通过 Apple 的工具学习 iPhone 开发获得了很多乐趣)。
有很多事情要考虑。价值是如此抽象。如果我们谈论成本以及它是否值得,答案归结为我的第一个要点:如果这是为了生意,如果你能得到工作,你就会马上赚回你的钱。
所以……这就是我所能做到的客观。这是您可能会问自己的简短列表,但这是一个起点。
就个人而言(让我们暂时放弃客观性),我喜欢并使用两者。我很高兴我首先了解了 Apple 堆栈。当我已经熟悉 Apple 的世界时,我更容易开始使用
MonoTouch。正如其他人所说,您仍将使用 CocoaTouch——它只是在一个 .Net 化的环境中。
但不止于此。没有使用过 MonoTouch 的人往往会停在那里——“这是一个包装器等等等等”——那不是 MonoTouch。
MonoTouch 让您可以访问 CocoaTouch 必须提供的功能,同时还可以让您访问 .Net 必须提供的(一个子集),一些人觉得更舒服的
IDE(我是其中之一),与 Interface Builder 更好的集成,虽然你不会完全忘记内存管理,但你有很大的余地。
如果您不确定,请获取 Apple 的堆栈(它是免费的),并获取 MonoTouch 评估堆栈(它是免费的)。在您加入 Apple
的开发计划之前,两者都只能在模拟器上运行,但这足以帮助您确定您是否更喜欢其中一个,以及 MonoTouch 对您而言是否值 399 美元。
不要听那些狂热者的话——他们往往是那些没有使用他们所反对的技术的人:)
c# – MonoTouch v.Objective-C for new iPhone devs
所以,我想知道的是C#和Objective-C对于新程序员的相对优点,在这些方面:
>表现
>使用方便
>轻松学习
>可靠性(即,新的iOS版本是否会破坏MonoTouch应用程序?)
此外,在MonoTouch中撰写的内容对于使用Android的跨平台开发有什么好处?
解决方法
我不明白为什么你带上MonoTouch,考虑到你的团队没有C#/ .NET的经验.有许多其他框架,如MonoTouch,包括Titanium SDK(JavaScript),RubyMotion(Ruby)等等.所有这些都是伟大的,但正如我所看到的,主要是那些有各自语言经验的人.它们允许您使用您更熟悉的语言编写iOS应用程序,但具有以下缺点:
>性能可以和Objective-C中写的应用程序一样好,但通常有一点(有时甚至很多).
>学习资源不如iOS SDK / Objective-C那么丰富.有许多人想要制作iOS应用程序,而那些人有些使用这些框架,并且在它们之间被稀释.只有少部分可用于iOS开发的资源将用于任何给定的框架.
>这些框架基于iOS SDK / Objective-C,所以自然的发展总是落后于后.如果苹果在下一个版本的iOS SDK中推出了新的API,那么您必须等待这些框架的适应性(用Objective-C编写的应用程序可能会中断,但是将更容易处理基于点#2).
>大多数这些框架需要熟悉iOS SDK.您仍然需要知道应用程序在启动时调用 – (BOOL)应用程序:(UIApplication *)应用程序didFinishLaunchingWithOptions:(NSDictionary *)launchOptions方法,但另外您还需要记住如何将其转换为适当的方法MonoTouch:public override bool FinishedLaunching(UIApplication app,NSDictionary options). iOS SDK是巨大的,大多数iOS开发人员依靠苹果的文档来了解.因此,您将看到针对Objective-C编写的api文档,并将方法转换为您选择的框架.
> Objective-C生态系统不断发展,酷派新项目如CocoaPods,bwoken等.这些主要是开发Objective-C和Xcode.配置它们与您选择的框架一起工作几乎总是会导致您额外的时间和工作.
上述几点总体上使我不会太多地研究任何这些其他框架.他们都很酷,但是他们在采用方面的主要优点似乎是促进了Objective-C之外的深入技能的人员的开发,或允许小团队的跨平台开发缺乏投入Android和iOS的资源(和Windows Phone)程序员.希望利益超过上述用户的成本.
Also,would writing in MonoTouch have any benefits for cross-platform development with Android?
我想是这样.事实上,MonoTouch homepage将这作为使用框架的主要优点.我不太了解view / controller类,因为这些类似于将它们绑定到UIKit中,但封装在模型中的逻辑应该是相当容易的端口.
漫长的故事,我想你和你的团队应该坚持使用Objective-C进行iOS开发.
C#Constructor重载:new object.FromOtherObject()?
NodeA nodea = new NodeA(); NodeB nodeb = new NodeB.FromNodeA(nodea);
我一直在谷歌搜索几个小时,但未能找到办法做到这一点.我想出的最好的解决方案是;
public NodeB() { } public static NodeB FromNodeA(NodeA theNodeA) { NodeB b = new NodeB(); b.Value = theNodeA.value; // etc.. }
但是这使代码看起来更像一个时髦的东西;
NodeB b = NodeB.FromNodeA(nodea);
理想情况下,我希望能够这样做:
NodeB b = new NodeB().FromNodeA(nodea);
编辑;
或者是静态方法我已经做了更多(传统上)正确的方法来完成这个?
解决方法
NodeB nodeB = new NodeB(nodeA);
…但是采用工厂方法也是一种非常惯用的解决方案.它具有各种好处,包括能够使用具有不同名称但具有相同参数类型的多种方法 – 例如,
TimeSpan.FromSeconds(...) TimeSpan.FromMinutes(...)
它还允许该方法更灵活:
>在某些情况下它可能返回null(例如,对于空输入)
>它可以返回对现有对象的引用
>它可以返回子类的实例(例如Encoding.GetEncoding)
>您可以将方法组转换为委托,这对LINQ操作很方便(不需要lambda表达式)
使它成为构造函数的一个好处是,如果你有一个NodeB的子类,那么它可以有一个构造函数,它也将NodeA和链带到NodeB(NodeA)构造函数.在没有代码重复的情况下使用工厂方法方法很难实现相同的功能.
根据Alessandro的评论,您可以拥有一个用户定义的转换运算符,无论是显式还是隐式.我会对隐式转换非常小心 – 当时它们可能感觉像个好主意,但最终会导致代码在以后不清楚.
最后,你也可以在NodeA上使用ToNodeB()方法 – 直接实现,或者作为扩展方法.
所以为了解决这个问题,以下是“用户代码”的外观选项:
NodeA nodeA = ...; // One of... NodeB nodeB = nodeA; // Implicit conversion NodeB nodeB = (NodeB) nodeA; // Explicit conversion NodeB nodeB = new NodeB(nodeA); // Constructor NodeB nodeB = NodeB.FromNodeA(nodeA); // Factory method NodeB nodeB = nodeA.ToNodeB(); // Instance or extension method on NodeA
cannot be found on object of type xx.CacheExpressionRootObject
0 环境
系统环境:win10
编辑器:IDEA
1 前言->环境搭建
1-1 pom依赖
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.8.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>org.javaboy</groupId>
<artifactId>chapter09-cacheredis</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>chapter09-cacheredis</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-cache</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
1-2 properties(redis的基本配置以及缓存名的配置)
spring.redis.host=127.0.0.1
spring.redis.password=123456
spring.redis.port=6379
spring.redis.database=0
spring.cache.cache-names=c1
1-3 Application启动项添加
1-4 自定义KeyGenerator
@Component
public class MyKeyGen implements KeyGenerator {
@Override
public Object generate(Object o, Method method, Object... objects) {
return method.getName()+":"+ Arrays.toString(objects);
}
1-5 service层
@Service
//@CacheConfig(cacheNames = "c1")
public class BookService {
// key = "#methodName"
// key = "#method.name"
// key = "#caches[0]"
// key = "#args[0]"
// @Cacheable(cacheNames = "c1",key = "#caches[0]")
@Cacheable(cacheNames = "c1",key = "''myKeyGen''")
public Book getUserById(Integer id){
System.out.println("book>>>>>>" + id);
Book book = new Book();
book.setId(id);
return book;
}
}
1-6 单元测试
@Autowired
BookService bookService;
@Test
public void contextLoads() {
Book book = bookService.getUserById(1);
Book book1 = bookService.getUserById(1);
System.err.println("book --->>" + book);
System.err.println("book1 --->>" + book1);
}
2 报错
key = "''''" (需要内嵌一下单引号 不然会报错)
CRM 系统和 ERP 系统有哪些区别?企业如何在二者之间做出选择?


在如今快节奏商业世界中,管理客户关系、优化企业资源是成功的基石。为了达到这些目标,企业一般借助 CRM 管理系统和 ERP 资源规划系统。尽管这俩系统都是必不可少的,但它们不能彼此取代,了解它们的差别是很重要的。在本文中,我们将探讨企业使用 CRM 系统与 ERP 系统的区别,并介绍他们的特点 / 作用 / 优点和区别。
CRM 的定义
CRM 是管理与客户互动和关系的一种做法。它涉及收集和分析客户数据以提高客户满意度、保留率和忠诚度。
CRM 系统可帮助企业自动化和简化面向客户的流程,例如营销、销售和客户服务。目标是为客户提供个性化和积极的体验,从而增加收入和品牌忠诚度。
CRM 的主要特点
CRM 系统的一些主要功能包括:
联系人管理:存储和组织客户信息,例如姓名、地址、电话号码和电子邮件地址。
销售渠道管理:跟踪销售线索和商机、管理销售渠道和预测销售。
营销自动化:自动化营销活动,例如电子邮件营销和社交媒体广告。
客户服务:管理客户查询和支持请求、跟踪客户互动和解决问题。
分析和报告:分析客户数据以确定趋势和改进机会。
ERP 的定义
企业资源规划系统(ERP)是指管理和整合公司核心业务流程和资源的做法。
ERP 系统通常包括财务、会计、人力资源、库存管理、供应链管理和制造等功能模块。目标是提供公司运营的集中视图,简化流程,并提高可见性和控制力。
ERP 的主要特点
ERP 系统的一些主要功能包括:
财务管理:管理财务交易,例如应付账款、应收账款和总账。
人力资源管理:管理员工信息、工资单、福利和绩效。
库存管理:跟踪库存水平、订单和发货。
供应链管理:管理从供应商到客户的商品和服务流。
制造:规划和管理生产流程,包括调度、质量控制和资源分配。
CRM 系统和 ERP 系统的区别
CRM 和 ERP 系统之间的差别是明显的,针对希望选择其中一两个系统的公司来说,把握这些差异至关重要。CRM 的关键是管理客户交互和关系,而 ERP 的关键是管理公司范围之内运营和资源。
CRM 系统旨在帮助企业提升客户满意率、保留率和满意率,ERP 系统旨在帮助企业简化和优化重要工作内容。就管理数据类型来讲,CRM 系统的关键管理与客户相关的数据,如客户信息、销售商机管理、客户服务和营销活动管理。
比较之下,ERP 系统管理广泛数据,包含会计买卖、库存水平、生产规划与员工信息。ERP 系统管理的信息一般比 CRM 系统管理的信息更复杂、更多样化。
CRM 和 ERP 系统的另一个显著区别是它们功能。CRM 系统提供销售自动化、客户服务管理、营销自动化等业务与能力。这种系统旨在帮助企业获取和吸引客户,改进客户关联。
比较之下,ERP 系统给予会计、供应链、制造等服务与水平。这种系统旨在帮助公司管理其核心运营和资源。CRM 系统一般用于零售、酒店和医疗健康行业。在各行各业,客户关系对成功至关重要,ERP 系统一般用于生产、分销和物流领域。
在各个行业中,高效和简化的经营至关重要。该系统帮助企业管理库存、生产与供应链流程,提升其运行,完成最高效率。
总的来说,希望在 CRM 或 ERP 间做出选择的企业应仔细斟酌其实际需求与目标。CRM 系统尤其适合那些希望改进客户关联和营销的企业,而 ERP 系统尤其适合那些希望简化其核心运营和资源的企业。针对希望优化运营、改进客户关联的公司来说,把握 CRM 与 ERP 系统的区别至关重要。
关于如何在 MonoTouch 和 Objective-C 之间做出选择?的问题就给大家分享到这里,感谢你花时间阅读本站内容,更多关于c# – MonoTouch v.Objective-C for new iPhone devs、C#Constructor重载:new object.FromOtherObject()?、cannot be found on object of type xx.CacheExpressionRootObject、CRM 系统和 ERP 系统有哪些区别?企业如何在二者之间做出选择?等相关知识的信息别忘了在本站进行查找喔。
本文将分享Node.js:由于 node-sass 和 node-gyp,Python 未找到异常的详细内容,并且还将对由于找不到node.dll进行详尽解释,此外,我们还将为大家带来关于/bin/sh: node-sass: 命令未找到 - 在原子中失败,在 VSCode 中工作、Beanstalk:Node.js部署 – 由于权限被拒绝,node-gyp失败、heroku node.js bash:node:命令未找到、node gyp安装canvas原生模块编译node pregyp详解的相关知识,希望对你有所帮助。
本文目录一览:- Node.js:由于 node-sass 和 node-gyp,Python 未找到异常(由于找不到node.dll)
- /bin/sh: node-sass: 命令未找到 - 在原子中失败,在 VSCode 中工作
- Beanstalk:Node.js部署 – 由于权限被拒绝,node-gyp失败
- heroku node.js bash:node:命令未找到
- node gyp安装canvas原生模块编译node pregyp详解
Node.js:由于 node-sass 和 node-gyp,Python 未找到异常(由于找不到node.dll)
突然在我的一个詹金斯环境中构建开始失败,而在本地机器上它似乎工作正常,因为我安装了 python,
从日志中我能够检测到问题出在内部依赖关系上,即来自 node-sass v3.8.0的 node-gyp* v3.5.0
,当我通过访问这个关于 node-gyp 进行研究并发现需要安装 Python
的先决条件时. *
所以我的问题是,我可以安装什么版本的 node-sass 来绕过它,或者是否有更好的解决方案,因为直到今天早上我的构建在同一环境中运行良好。
节点 v5.10.1
错误日志
gyp verb check python checking for Python executable "python2" in the PATHgyp verb `which` failed Error: not found: python2gyp verb `which` failed at getNotFoundError (C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\which\which.js:13:12)gyp verb `which` failed at F (C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\which\which.js:68:19)gyp verb `which` failed at E (C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\which\which.js:80:29)gyp verb `which` failed at C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\which\which.js:89:16gyp verb `which` failed at C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\isexe\index.js:44:5gyp verb `which` failed at C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\isexe\windows.js:29:5gyp verb `which` failed at FSReqWrap.oncomplete (fs.js:82:15)gyp verb `which` failed python2 { [Error: not found: python2] code: ''ENOENT'' }gyp verb check python checking for Python executable "python" in the PATHgyp verb `which` failed Error: not found: pythongyp verb `which` failed at getNotFoundError (C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\which\which.js:13:12)gyp verb `which` failed at F (C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\which\which.js:68:19)gyp verb `which` failed at E (C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\which\which.js:80:29)gyp verb `which` failed at C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\which\which.js:89:16gyp verb `which` failed at C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\isexe\index.js:44:5gyp verb `which` failed at C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\isexe\windows.js:29:5gyp verb `which` failed at FSReqWrap.oncomplete (fs.js:82:15)gyp verb `which` failed python { [Error: not found: python] code: ''ENOENT'' }gyp verb could not find "python". checking python launcher gyp verb could not find "python". guessing location gyp verb ensuring that file exists: C:\Python27\python.exegyp ERR! configure error gyp ERR! stack Error: Can''t find Python executable "python", you can set the PYTHON env variable.gyp ERR! stack at Object.failNoPython (C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\node-gyp\lib\configure.js:454:19)gyp ERR! stack at Object.<anonymous> (C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\node-gyp\lib\configure.js:480:16)gyp ERR! stack at C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\graceful-fs\polyfills.js:284:29gyp ERR! stack at FSReqWrap.oncomplete (fs.js:82:15)gyp ERR! System Windows_NT 6.3.9600gyp ERR! command "C:\\Program Files\\nodejs\\node.exe" "C:\\Program Files (x86)\\Jenkins\\jobs\\NdbSite-hot-fix-Manual-PreBuild\\workspace\\src\\NdbSite.UI\\node_modules\\node-gyp\\bin\\node-gyp.js" "rebuild" "--verbose" "--libsass_ext=" "--libsass_cflags=" "--libsass_ldflags=" "--libsass_library="gyp ERR! cwd C:\Program Files (x86)\Jenkins\jobs\NdbSite-hot-fix-Manual-PreBuild\workspace\src\NdbSite.UI\node_modules\node-sassgyp ERR! node -v v5.10.1gyp ERR! node-gyp -v v3.5.0gyp ERR! not ok Build failed
任何想法都非常感谢,谢谢。
答案1
小编典典Node-sass 在安装时会尝试为您的平台下载二进制文件。Node 5 受 3.8 支持https://github.com/sass/node-
sass/releases/tag/v3.8.0 如果您的 Jenkins 无法下载预构建的二进制文件,那么您需要遵循 Node-gyp
上的平台要求自述文件(Python2、VS 或 MSBuild,…)如果可能,我建议您将 Node 更新到至少 6,因为 Node 不再支持
5。如果要升级到 8,则需要将 node-sass 更新到 4.5.3
/bin/sh: node-sass: 命令未找到 - 在原子中失败,在 VSCode 中工作
如何解决/bin/sh: node-sass: 命令未找到 - 在原子中失败,在 VSCode 中工作?
我尝试将 sass 自动编译器添加到文本编辑器原子中,但它在编译时一直返回错误。我在 VSCode 中尝试过,它在那里工作得非常好。 有谁知道为什么它在原子中不断失败?我真的很想使用那个文本编辑器。
解决方法
暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!
如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。
小编邮箱:dio#foxmail.com (将#修改为@)
Beanstalk:Node.js部署 – 由于权限被拒绝,node-gyp失败
gyp ERR! stack Error: EACCES: permission denied,mkdir
‘/tmp/deployment/application/node_modules/heapdump/build’
虽然错误不是特定于包,但任何node-gyp调用都会失败。
AWS控制台中的ERROR事件显示:
[Instance: i-12345] Command Failed on instance. Return
code: 1 Output:
(TruncATED)…/opt/elasticbeanstalk/containerfiles/ebnode.py”,line
180,in npm_install raise e subprocess.CalledProcessError: Command
‘[‘/opt/elasticbeanstalk/node-install/node-v6.10.0-linux-x64/bin/npm’,
‘–production’,‘install’]’ returned non-zero exit status 1. Hook
/opt/elasticbeanstalk/hooks/appdeploy/pre/50npm.sh Failed. For more
detail,check /var/log/eb-activity.log using console or EB CLI.
和eb-activity.log包含上述npm错误。
通过上载不包含node_modules的.zip文件手动部署应用程序。即它没有通过eb命令行工具部署。
解决方法
解决方案是将文件.npmrc添加到具有以下内容的应用程序:
# Force npm to run node-gyp also as root,preventing permission denied errors in AWS with npm@5 unsafe-perm=true
(或者以任何其他方式配置npm。(虽然在/opt/elasticbeanstalk/env.vars中设置npm_config_unsafe_perm = true对我来说不起作用。)
说明
npm install由root用户运行,但是它为某些包触发的node-gyp进程由默认用户ec2-user运行。该用户无法访问由npm安装运行创建并由root拥有的/ tmp / deployment / application / node_modules /目录。 (并且它可能也缺少访问/tmp/.npm和由此创建的/tmp/.config。)通过启用unsafe-perm,我们强制npm也以root身份运行node-gyp,从而避免了这个问题。
(就我个人而言,我更愿意以ec2-user而不是root身份运行,但我想这会涉及更多:-))
积分
unreal0 has pointed me to the solution
相关问题
> Node.js deployment fails on Amazon Elastic Beanstalk due to directory permissions
heroku node.js bash:node:命令未找到
我的procfile如下:
web: node web.js
和我的package.json文件:
{ "name": "fuuzik","version": "0.0.1","dependencies": { "express": "3.x","jade":"*","mime-magic":"*" },"engines": { "node": "0.8.x","npm": "1.1.x" } }
因此,在我提交并推送heroku检测到它是一个节点应用程序正确并正确构建我的依赖,甚至说它已部署..但应用程序在部署时立即崩溃并且heroku日志返回:
2012-08-29T08:52:14+00:00 heroku[api]: Deploy d9fdb17 by he610@doc.ic.ac.uk 2012-08-29T08:52:14+00:00 heroku[web.1]: State changed from crashed to starting 2012-08-29T08:52:14+00:00 heroku[slugc]: Slug compilation finished 2012-08-29T08:52:16+00:00 heroku[web.1]: Starting process with command `node web.js` 2012-08-29T08:52:16+00:00 app[web.1]: bash: node: command not found 2012-08-29T08:52:17+00:00 heroku[web.1]: Process exited with status 127 2012-08-29T08:52:17+00:00 heroku[web.1]: State changed from starting to crashed
foreman运行正常,根目录周围有几个.PHP文件(因为我正在移植一些旧代码),但我很确定应该被procfiles的逻辑所允许
根据要求,这里是本地npm安装的输出:
--[/DEBUG]-- jade@0.27.2 node_modules/jade ├── commander@0.6.1 └── mkdirp@0.3.0 express@3.0.0rc3 node_modules/express ├── methods@0.0.1 ├── range-parser@0.0.4 ├── fresh@0.1.0 ├── cookie@0.0.4 ├── crc@0.2.0 ├── commander@0.6.1 ├── debug@0.7.0 ├── mkdirp@0.3.3 ├── send@0.0.3 (mime@1.2.6) └── connect@2.4.3 (pause@0.0.1,bytes@0.1.0,qs@0.4.2,formidable@1.0.11) mime-magic@0.3.0 node_modules/mime-magic
这是推送时的git日志(它有点大,所以我把它连接起来):
http://pastebin.com/d424TBfR
任何帮助赞赏!
解决方法
显然,procfile指示heroku使用节点main.js运行应用程序,但节点不是有效命令,因为它不包含在PATH varialbe中,或类似.
通过删除procfile,heroku检测到该应用程序是一个流星应用程序,并使用节点的二进制文件以完整路径运行它.
另外,请记住必须以http://开头设置ROOT_URL
node gyp安装canvas原生模块编译node pregyp详解
关于node-gyp
node-gyp
是一个用 Node.js 编写的跨平台命令行工具,用于为 Node.js 编译本机插件模块。它包含之前由 Chromium 团队使用的 gyp-next项目的供应副本,扩展以支持 Node.js 原生插件的开发。
node-gyp is a cross-platform command-line tool written in Node.js for compiling native addon modules for Node.js. It contains a vendored copy of the gyp-next project that was previously used by the Chromium team, extended to support the development of Node.js native addons.
node是跨平台的,那么对于任何的node模块理论也是应该是跨平台的。然而,有些node模块直接或间接使用原生C/C++代码,这些东西要跨平台,就需要使用源码根据实际的操作平台环境进行原生模块编译。通常我们开发环境为macOS或Windows,而生产环境为Linux的各种发行版,这将导致我们的开发工作变得沉重不堪。那我们是否可以跳过node-gyp的编译过程?
node-pre-gyp
node-gyp的编译是让人难受的过程,所以社区出现了node-pre-gyp
和prebuild-install
,它们都会优先下载插件作者预编译的二进制文件,当二进制文件下载出现问题时,再使用node-gyp进行编译兜底。
但因为我们网络环境的特殊性,这些二进制文件我们大概率是不会下载成功的,接下来一起来看看在canvas的安装过程中node-pre-gyp
干了什么事。
关于prebuild-install
参考姊妹文【Nodejs】关于原生模块编译node-gyp + prebuild-install (以安装 better-sqlite3为例)
canvas安装过程追踪
canvas就使用了node-pre-gyp来优化构建过程
1. 安装canvas
关于install我们需要了解一点东西, 通常基于表象我们都会认为npm下载解压并释放到node_modules后就完成了安装过程,但实际上npm还会检查package中是否配置了install命令,存在就会立即执行,这也是原生模块在下载完成后会自动构建的基础。
npm install canvas
2. canvas的package的命令脚本
可以看到canvas配置了install命令,所以npm下载canvas后立即执行了
node-pre-gyp install --fallback-to-build --update-binary
{ ..., "scripts": { "prebenchmark": "node-gyp build", "benchmark": "node benchmarks/run.js", "lint": "standard examples/*.js test/server.js test/public/*.js benchmarks/run.js lib/context2d.js util/has_lib.js browser.js index.js", "test": "mocha test/*.test.js", "pretest-server": "node-gyp build", "test-server": "node test/server.js", "generate-wpt": "node ./test/wpt/generate.js", "test-wpt": "mocha test/wpt/generated/*.js", "install": "node-pre-gyp install --fallback-to-build --update-binary", "dtslint": "dtslint types" } }
3. node-pre-gyp install命令
node-pre-gyp命令最终链接到了@mapbox/node-pre-gyp/lib/main.js
,根据参数install
最终进入@mapbox/node-pre-gyp/lib/install.js
执行
4. 下载预构建的二进制文件
可以看到node-pre-gyp
先检查项目本地是否已经存在二进制构建文件,当不存在时进入用户本地查找,当用户本地也不存在时会执行http下载任何,接下来我们在看看http链接如何生成
existsAsync(binary_module, (found) => { if (!update_binary) { if (found) { console.log(''['' + package_json.name + ''] Success: "'' + binary_module + ''" already installed''); console.log(''Pass --update-binary to reinstall or --build-from-source to recompile''); return callback(); } log.info(''check'', ''checked for "'' + binary_module + ''" (not found)''); } makeDir(to).then(() => { const fileName = from.startsWith(''file://'') && from.slice(''file://''.length); if (fileName) { extract_from_local(fileName, to, after_place); } else { place_binary(from, to, opts, after_place); } }).catch((err) => { after_place(err); }); function after_place(err) { if (err && should_do_fallback_build) { print_fallback_error(err, opts, package_json); return do_build(gyp, argv, callback); } else if (err) { return callback(err); } else { console.log(''['' + package_json.name + ''] Success: "'' + binary_module + ''" is installed via remote''); return callback(); } } });
其中from变量即预构件二进制文件地址,指向opts.hosted_tarball,源码只保留了核心部分,完整源码请查阅@mapbox/node-pre-gyp/lib/util/versioning.js
const host = process.env[''npm_config_'' + validModuleName + ''_binary_host_mirror''] || package_json.binary.host; opts.host = fix_slashes(eval_template(host, opts)); ... opts.remote_path = package_json.binary.remote_path ? drop_double_slashes(fix_slashes(eval_template(package_json.binary.remote_path, opts))) : default_remote_path; ... opts.hosted_path = url.resolve(opts.host, opts.remote_path); opts.hosted_tarball = url.resolve(opts.hosted_path, opts.package_name);
可以看到node-pre-gyp
会读取配置文件中是否配置了{包名}_binary_host_mirror,否则读取待构建的插件package.json中的binary.host
配置项,所以在prebuild-install
中可以生效的{p包名}_binary_host在node-pre-gyp
中是无效的,所以针对原生插件我们需要查看插件使用的node-pre-gyp
还是prebuild-install
来灵活调整.npmrc
中的预构件二进制文件下载镜像源
让node-pre-gyp通过淘宝源下载预构建文件
npm提供了.npmrc
配置文件并注入到进程的env环境变量中,从上面的源码可知,node-pre-gyp
会优先读取npm_config_{包名}_binary_host_mirror(.npmrc中的变量均会被npm添加npm_config_前缀, 所以我们配置时无需添加npm_config_前缀),另外需要值得注意的是npm会将.npmrc
中的键以下划线的方式组织且任何非数字和字母的字符将会被替换为_
。所以以canvas举例来说,配置如下
canvas_binary_host_mirror=https://registry.npmmirror.com/-/binary/canvas
鉴于prebuild-install
兼容性更好,针对原生模块我们在.npmrc
中以{包名}_binary_host_mirror={mirror}的格式配置预构建文件下载镜像
以上就是node gyp安装canvas原生模块编译node pregyp详解的详细内容,更多关于node gyp安装canvas的资料请关注其它相关文章!
- npm install --save 、--save-dev 、-D、-S 的区别与NODE_ENV的配置方法
- node.js使用npm 安装插件时提示install Error: ENOENT报错的解决方法
- nodejs npm install全局安装和本地安装的区别
- better sqlite3安装node gyp原生模块编译prebuild-install
关于Node.js:由于 node-sass 和 node-gyp,Python 未找到异常和由于找不到node.dll的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于/bin/sh: node-sass: 命令未找到 - 在原子中失败,在 VSCode 中工作、Beanstalk:Node.js部署 – 由于权限被拒绝,node-gyp失败、heroku node.js bash:node:命令未找到、node gyp安装canvas原生模块编译node pregyp详解等相关内容,可以在本站寻找。
本文标签: