1. python中为什么可以一直用点属性方法
在python 的数据结构中使用. 方式获取属性值,其实是底层实现了__getattribute__ 魔法方法。
例如代码如下:
class Person(object):
def __init__(self,name,age):
self.name = name
self.age = age
def __getattribute__(self, item):
return "{} good luck".format(item)
if __name__ == '__main__':
p=Person("tom",18)
p.age # 获取属性的同时就会触发 __getattribute_
还有就是字典的取值方式 经过 [] 来取值,其实他是实现了__getitem__ 魔法方法;
你可以自定义一个类,重写__getitem__ 这个方法来实现 属性也可以这么取值。
2. Python 有什么奇技淫巧
Python奇技淫巧
当发布python第三方package时, 并不希望代码中所有的函数或者class可以被外部import, 在 __init__.py 中添加 __all__ 属性,
该list中填写可以import的类或者函数名, 可以起到限制的import的作用, 防止外部import其他函数或者类
#!/usr/bin/env python
# -*- coding: utf-8 -*-
frombaseimportAPIBase
fromclientimportClient
fromdecoratorimportinterface, export, stream
fromserverimportServer
fromstorageimportStorage
fromutilimport(LogFormatter, disable_logging_to_stderr,
enable_logging_to_kids, info)
__all__ = ['APIBase','Client','LogFormatter','Server',
'Storage','disable_logging_to_stderr','enable_logging_to_kids',
'export','info','interface','stream']
with的魔力
with语句需要支持 上下文管理协议的对象 , 上下文管理协议包含 __enter__ 和 __exit__ 两个方法. with语句建立运行时上下文需要通过这两个方法执行 进入和退出 操作.
其中 上下文表达式 是跟在with之后的表达式, 该表示大返回一个上下文管理对象
# 常见with使用场景
withopen("test.txt","r")asmy_file:# 注意, 是__enter__()方法的返回值赋值给了my_file,
forlineinmy_file:
print line
详细原理可以查看这篇文章, 浅谈 Python 的 with 语句
知道具体原理, 我们可以自定义支持上下文管理协议的类, 类中实现 __enter__ 和 __exit__ 方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
classMyWith(object):
def__init__(self):
print"__init__ method"
def__enter__(self):
print"__enter__ method"
returnself# 返回对象给as后的变量
def__exit__(self, exc_type, exc_value, exc_traceback):
print"__exit__ method"
ifexc_tracebackisNone:
print"Exited without Exception"
returnTrue
else:
print"Exited with Exception"
returnFalse
deftest_with():
withMyWith()asmy_with:
print"running my_with"
print"------分割线-----"
withMyWith()asmy_with:
print"running before Exception"
raiseException
print"running after Exception"
if__name__ =='__main__':
test_with()
执行结果如下:
__init__ method
__enter__ method
running my_with
__exit__ method
ExitedwithoutException
------分割线-----
__init__ method
__enter__ method
running before Exception
__exit__ method
ExitedwithException
Traceback(most recent call last):
File"bin/python", line34,in<mole>
exec(compile(__file__f.read(), __file__, "exec"))
File"test_with.py", line33,in<mole>
test_with()
File"test_with.py", line28,intest_with
raiseException
Exception
证明了会先执行 __enter__ 方法, 然后调用with内的逻辑, 最后执行 __exit__ 做退出处理, 并且, 即使出现异常也能正常退出
filter的用法
相对 filter 而言, map和rece使用的会更频繁一些, filter 正如其名字, 按照某种规则 过滤 掉一些元素
#!/usr/bin/env python
# -*- coding: utf-8 -*-
lst = [1,2,3,4,5,6]
# 所有奇数都会返回True, 偶数会返回False被过滤掉
print filter(lambda x: x % 2!=0, lst)
#输出结果
[1,3,5]
一行作判断
当条件满足时, 返回的为等号后面的变量, 否则返回else后语句
lst = [1,2,3]
new_lst = lst[0]iflstisnotNoneelseNone
printnew_lst
# 打印结果
1
装饰器之单例
使用装饰器实现简单的单例模式
# 单例装饰器
defsingleton(cls):
instances = dict() # 初始为空
def_singleton(*args, **kwargs):
ifclsnotininstances:#如果不存在, 则创建并放入字典
instances[cls] = cls(*args, **kwargs)
returninstances[cls]
return_singleton
@singleton
classTest(object):
pass
if__name__ =='__main__':
t1 = Test()
t2 = Test()
# 两者具有相同的地址
printt1, t2
staticmethod装饰器
类中两种常用的装饰, 首先区分一下他们
普通成员函数, 其中第一个隐式参数为 对象
classmethod装饰器 , 类方法(给人感觉非常类似于OC中的类方法), 其中第一个隐式参数为 类
staticmethod装饰器 , 没有任何隐式参数. python中的静态方法类似与C++中的静态方法
#!/usr/bin/env python
# -*- coding: utf-8 -*-
classA(object):
# 普通成员函数
deffoo(self, x):
print "executing foo(%s, %s)"% (self, x)
@classmethod# 使用classmethod进行装饰
defclass_foo(cls, x):
print "executing class_foo(%s, %s)"% (cls, x)
@staticmethod# 使用staticmethod进行装饰
defstatic_foo(x):
print "executing static_foo(%s)"% x
deftest_three_method():
obj = A()
# 直接调用噗通的成员方法
obj.foo("para")# 此处obj对象作为成员函数的隐式参数, 就是self
obj.class_foo("para")# 此处类作为隐式参数被传入, 就是cls
A.class_foo("para")#更直接的类方法调用
obj.static_foo("para")# 静态方法并没有任何隐式参数, 但是要通过对象或者类进行调用
A.static_foo("para")
if__name__=='__main__':
test_three_method()
# 函数输出
executing foo(<__main__.Aobject at0x100ba4e10>, para)
executing class_foo(<class'__main__.A'>,para)
executing class_foo(<class'__main__.A'>,para)
executing static_foo(para)
executing static_foo(para)
property装饰器
定义私有类属性
将 property 与装饰器结合实现属性私有化( 更简单安全的实现get和set方法 )
#python内建函数
property(fget=None, fset=None, fdel=None, doc=None)
fget 是获取属性的值的函数, fset 是设置属性值的函数, fdel 是删除属性的函数, doc 是一个字符串(like a comment).从实现来看,这些参数都是可选的
property有三个方法 getter() , setter() 和 delete() 来指定fget, fset和fdel。 这表示以下这行
classStudent(object):
@property #相当于property.getter(score) 或者property(score)
defscore(self):
returnself._score
@score.setter #相当于score = property.setter(score)
defscore(self, value):
ifnotisinstance(value, int):
raiseValueError('score must be an integer!')
ifvalue <0orvalue >100:
raiseValueError('score must between 0 ~ 100!')
self._score = value
iter魔法
通过yield和 __iter__ 的结合, 我们可以把一个对象变成可迭代的
通过 __str__ 的重写, 可以直接通过想要的形式打印对象
#!/usr/bin/env python
# -*- coding: utf-8 -*-
classTestIter(object):
def__init__(self):
self.lst = [1,2,3,4,5]
defread(self):
foreleinxrange(len(self.lst)):
yieldele
def__iter__(self):
returnself.read()
def__str__(self):
return','.join(map(str, self.lst))
__repr__ = __str__
deftest_iter():
obj = TestIter()
fornuminobj:
printnum
printobj
if__name__ =='__main__':
test_iter()
神奇partial
partial使用上很像C++中仿函数(函数对象).
在stackoverflow给出了类似与partial的运行方式
defpartial(func, *part_args):
defwrapper(*extra_args):
args = list(part_args)
args.extend(extra_args)
returnfunc(*args)
returnwrapper
利用用闭包的特性绑定预先绑定一些函数参数, 返回一个可调用的变量, 直到真正的调用执行
#!/usr/bin/env python
# -*- coding: utf-8 -*-
fromfunctoolsimportpartial
defsum(a, b):
returna + b
deftest_partial():
fun = partial(sum, 2)# 事先绑定一个参数, fun成为一个只需要一个参数的可调用变量
printfun(3)# 实现执行的即是sum(2, 3)
if__name__ =='__main__':
test_partial()
# 执行结果
5
神秘eval
eval我理解为一种内嵌的python解释器(这种解释可能会有偏差), 会解释字符串为对应的代码并执行, 并且将执行结果返回
看一下下面这个例子
#!/usr/bin/env python
# -*- coding: utf-8 -*-
deftest_first():
return3
deftest_second(num):
returnnum
action = { # 可以看做是一个sandbox
"para":5,
"test_first": test_first,
"test_second": test_second
}
deftest_eavl():
condition = "para == 5 and test_second(test_first) > 5"
res = eval(condition, action) # 解释condition并根据action对应的动作执行
printres
if__name__ =='_
exec
exec在Python中会忽略返回值, 总是返回None, eval会返回执行代码或语句的返回值
exec 和 eval 在执行代码时, 除了返回值其他行为都相同
在传入字符串时, 会使用 compile(source, '<string>', mode) 编译字节码. mode的取值为 exec 和 eval
#!/usr/bin/env python
# -*- coding: utf-8 -*-
deftest_first():
print"hello"
deftest_second():
test_first()
print"second"
deftest_third():
print"third"
action = {
"test_second": test_second,
"test_third": test_third
}
deftest_exec():
exec"test_second"inaction
if__name__ =='__main__':
test_exec() # 无法看到执行结果
getattr
getattr(object, name[, default]) Return the value of
the named attribute of object. name must be a string. If the string is
the name of one of the object’s attributes, the result is the value of
that attribute. For example, getattr(x, ‘foobar’) is equivalent to
x.foobar. If the named attribute does not exist, default is returned if
provided, otherwise AttributeError is raised.
通过string类型的name, 返回对象的name属性(方法)对应的值, 如果属性不存在, 则返回默认值, 相当于object.name
# 使用范例
classTestGetAttr(object):
test = "test attribute"
defsay(self):
print"test method"
deftest_getattr():
my_test = TestGetAttr()
try:
printgetattr(my_test,"test")
exceptAttributeError:
print"Attribute Error!"
try:
getattr(my_test, "say")()
exceptAttributeError:# 没有该属性, 且没有指定返回值的情况下
print"Method Error!"
if__name__ =='__main__':
test_getattr()
# 输出结果
test attribute
test method
命令行处理
defprocess_command_line(argv):
"""
Return a 2-tuple: (settings object, args list).
`argv` is a list of arguments, or `None` for ``sys.argv[1:]``.
"""
ifargvisNone:
argv = sys.argv[1:]
# initialize the parser object:
parser = optparse.OptionParser(
formatter=optparse.TitledHelpFormatter(width=78),
add_help_option=None)
# define options here:
parser.add_option( # customized description; put --help last
'-h','--help', action='help',
help='Show this help message and exit.')
settings, args = parser.parse_args(argv)
# check number of arguments, verify values, etc.:
ifargs:
parser.error('program takes no command-line arguments; '
'"%s" ignored.'% (args,))
# further process settings & args if necessary
returnsettings, args
defmain(argv=None):
settings, args = process_command_line(argv)
# application code here, like:
# run(settings, args)
return0# success
if__name__ =='__main__':
status = main()
sys.exit(status)
读写csv文件
# 从csv中读取文件, 基本和传统文件读取类似
importcsv
withopen('data.csv','rb')asf:
reader = csv.reader(f)
forrowinreader:
printrow
# 向csv文件写入
importcsv
withopen('data.csv','wb')asf:
writer = csv.writer(f)
writer.writerow(['name','address','age'])# 单行写入
data = [
( 'xiaoming ','china','10'),
( 'Lily','USA','12')]
writer.writerows(data) # 多行写入
各种时间形式转换
只发一张网上的图, 然后差文档就好了, 这个是记不住的
字符串格式化
一个非常好用, 很多人又不知道的功能
>>>name ="andrew"
>>>"my name is {name}".format(name=name)
'my name is andrew'
3. 如何在python中实现一个自定义的列表或字典
在很多的python库之中,我们可以看到有的时候,库作者会使用一些很特殊的“列表”或者“字典”。虽然他们看起来很像是一个列表或者字典,但是使用的方法却又不一样,这是因为那不是真的python中原本的列表和字典,而是作者自己创建的。那么,我们如何可以创建我们自己的列表和字典呢?
前后都使用两个下划线的方法,一般被称之为魔法方法,比如我们常见的 init ,就是一种魔法方法。一般来说,我们自行定义变量名的时候,不要定义很像是魔法方法的变量名。魔法方法被定义后,可以在适当的时候自动被调用,一般不需要手动对其进行调用。
在python中,实现一个序列,我们需要以下四种魔法方法
另外,一般来说,错误的键应当引发TypeError异常,而错误的索引应当引发IndexError异常
在python的列表中,只能够使用数字作为索引,如果使用字符串的数字的话,那么会引发异常。因此,我们可以尝试一下,对原始的列表进行扩充,使其可以接受字符串作为列表的索引。
注意,这样的自建列表,存在很多问题,几乎全部的关于列表的方法都不能再被使用了。
为了解决正常列表的方法不能再被使用,我们可以考虑直接继承list,以此得到普通列表的所有方法。
4. Python魔法函数(特殊函数)
Python中如何实现运算符的重载,即实现例如a+b这样的运算符操作呢?
在C++中可以使用 operator 关键字实现运算符的重载。但是在Python中没有类似这样的关键字,所以要实现运算符的重载,就要用到Python的魔法函数。Python魔法函数是以双下划线开头,双下划线结尾的一组函数。我们在类定义中最常用到的 __init__ 函数就是这样一个魔法函数,它在创建类对象时被自动调用。
下面我们来看个简单的例子。
上述代码示例了几个魔法函数的用法。 __add__ 函数对应了二元运算符+,当执行a+b语句时,python就会自动调用a. add (b)。 对于上述例子中的v1+v2+v3,则相当于调用了(v1. add(v2)). add(v3)。
代码中还有一个在Python类定义经常使用的 __str__ 函数,当使用 str() 时会被调用。print函数对传入的参数都调用了str()将其转换成易读的字符串形式,便于打印输出,因而会调用类定义的__str__函数打出自定义的字符串。
代码中还有一个特殊的 __call__ 函数,该函数在将对象采用函数调用方式使用时被调用, 例如v1()相当于v1. call ()。
以上就是魔法函数的基本使用方法。常见的魔法函数我们可以使用 dir() 函数来查看。
输出结果为:
上述结果中形式为‘__函数名__’的函数为魔法函数,注意有些对象也是这种形式,例如__class__, __mole__等, 这些不是魔法函数。具体的魔法函数说明可以参考Python官方说明文档。
以上代码在Python3.6运行通过.
5. 如何学习python知乎
对于Python的学习人员需要掌握以下技术。
1.网络编程。
网络编程在生活和开发中无处不在,哪里有通讯就有网络,它可以称为是一切开发的"基石"。对于所有编程开发人员必须要知其然并知其所以然,所以网络部分将从协议、封包、解包等底层进行深入剖析。
2. 爬虫开发。
将网络一切数据作为资源,通过自动化程序进行有针对性的数据采集以及处理。爬虫开发项目包含跨越防爬虫策略、高性能异步IO、分布式爬虫等,并针对Scrapy框架源码进行深入剖析,从而理解其原理并实现自定义爬虫框架。
3.Web开发。
Web开发包含前端以及后端两大部分,前端部分,带你从"黑白"到"彩色"世界,手把手开发动态网页;后端部分,带你从10行代码开始到n万行来实现并使用自己的微型Web框架,框架讲解中涵盖了数据、组件、安全等多领域的知识,从底层了解其工作原理并可驾驭任何业内主流的Web框架。
4. IT自动化开发。
IT运维自动化是一组将静态的设备结构转化为根据IT服务需求动态弹性响应的策略,目的就是实现减少人工干预、降低人员成本以及出错概率,真刀真枪的带你开发企业中最常用的项目,从设计层面、框架选择、灵活性、扩展性、故障处理、以及如何优化等多个层面接触真实的且来源于各大互联网公司真实案例,如:堡垒机、CMDB、全网监控、主机管理等。
5. 金融分析。
金融分析包含金融知识和Python相关模块的学习,手把手带你从金融小白到开发量化交易策略的大拿。学习内容囊括Numpy\Pandas\Scipy数据分析模块等,以及常见金融分析策略如"双均线"、"周规则交易"、"羊驼策略"、"Dual Thrust 交易策略"等,让梦想照进现实,进入金融行业不再是个梦。
6. 人工智能+机器学习。
人工智能时代来临,率先引入深度机器学习课程。其中包含机器学习的基础概念以及常用知识,如:分类、聚类、回归、神经网络以及常用类库,并根据身边事件作为案例,一步一步经过预处理、建模、训练以及评估和参调等。人工智能是未来科技发展的新趋势,Python作为最主要的编程语言,势必有很好的发展前景,现在学习Python也是一个很好的机会。
6. python中的__str__函数作用
__str__方法:总结
在python中方法名如果是__xxxx__()的,那么就有特殊的功能,因此叫做“魔法”方法,当使用print输出对象的时候,只要自己定义了__str__(self)方法,那么就会打印从在这个方法中return的数据
例子1:如:
class Car:
def __init__(self, newWheelNum, newColor):
self.wheelNum = newWheelNum
self.color = newColor
def __str__(self):
msg = "嘿。。。我的颜色是" + self.color + "我有" + int(self.wheelNum) + "个轮胎..."
return msg
def move(self):
print('车在跑,目标:夏威夷')
BMW = Car(4, "白色")
print(BMW)
例子2:如:
class Cat:
"""定义了一个Cat类"""
#初始化对象
def __init__(self, new_name, new_age):
self.name = new_name
self.age = new_age
def __str__(self):
return "%s的年龄是:%d"%(self.name, self.age)
#方法
def eat(self):
print("猫在吃鱼....")
def drink(self):
print("猫正在喝kele.....")
def introce(self):
print("%s的年龄是:%d"%(self.name, self.age))
#创建一个对象
tom = Cat("汤姆", 40)
lanmao = Cat("蓝猫", 10)
print(tom)
print(lanmao)
运行结果:
汤姆的年龄是:40
蓝猫的年龄是:10
7. python:matplotlib,魔法函数%matplotlib notebook,plot里style='k--o'是什么意思呢
知乎自己看网页链接:
matplotlib的plot函数接受一组X和Y坐标,还可以通过color、marker和linestyle关键字传入指定的颜色、标记和线型,或者用一个表示颜色、标记和线型的格式字符串替代,两种方法是等效的。格式字符串中color、marker和linestyle可以任意排列,如'ko--','k--o','o--k'
8. python中魔法方法加减怎么用
Python中的列表中的元素不能直接相加减。
最佳的方式是将列表转换成Python中的科学计算包numpy包的array类型,再进行加减。
import
numpy
as
npa
=
np.array([1,2,3,4])b
=
np.array([7,8,9,10])s
=
a
+
b
9. 【python】魔法方法 :__getitem__ 、 __len__、__setitem__等的使用
在Python中,如果我们想实现创建类似于序列和映射的类(可以迭代以及通过[下标]返回元素),可以通过重写魔法方法 __getitem__、__setitem__、__delitem__、__len__ 方法去模拟。
__getitem__(self,key): 返回键对应的值。
__setitem__(self,key,value): 设置给定键的值
__delitem__(self,key): 删除给定键对应的元素。
__len__(): 返回元素的数量
【注释】只要实现了 __getitem__ 和 __len__ 方法,就会被认为是序列。
这些魔术方法的原理就是:当我们对类的属性item进行下标的操作时,首先会被 __getitem__()、__setitem__()、__delitem__() 拦截,从而执行我们在方法中设定的操作,如赋值,修改内容,删除内容等等。
这个方法应该以与键相关联的方式存储值,以便之后能够使用 __setitem__ 来获取。当然,这个对象可变时才需要实现这个方法。
举个栗子:
定义一副扑克牌(不包括大小王),对牌进行洗牌,然后发牌。
Output:
【注意】 :我们会发现output中,输出了: slice(1, 3, None) ,下面给出解释。
语法:
参数说明:
slice() 函数实现切片对象,主要用在切片操作函数里的参数传递。
举两个栗子来看看:
Output:
切片原理
output
(程序员必会的 hhhhh.....)
看看slice在python3.7中是怎么描述的:
10. python魔法,疑问
魔法方法是让你自己改的 不改当然没意义了 初学者说