炼数成金 门户 大数据 Python 查看内容

极简Python入门

2017-5-22 10:18| 发布者: 炼数成金_小数| 查看: 10021| 评论: 0|来自: 智能算法

摘要: 面向对象编程,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。在类变量的前加入__,就会变成私有变量。内部能访问,外部不能访问。私有变量的实现其实是对变量别名。从现有 ...

Python Java Hadoop 培训 C++ 方法

本文旨在帮助从总体上帮助了解Python的一些基本属性,具体的使用技巧需要通过不断实践积累

一、Python的基本特性



二、Python的类
面向对象编程,是一种程序设计思想。OOP把对象作为程序的基本单元,一个对象包含了数据和操作数据的函数。

1、类
创建办法:
    class Student(object):    pass
如果没有合适继承类,使用object类,所有类都会继承的类。通过__init__方法,可以将必须绑定的属性强制写入。
    class Student(object): def __init__(self, name, score):    self.name = name    self.score = score
第一参数永远是self,创建的实例本身。

2、访问限制
    在类变量的前加入__,就会变成私有变量。内部能访问,外部不能访问。私有变量的实现其实是对变量别名。
class Student(object):    
    def __init__(self, name, score):   
        self.__name = name
        self.__score = score
python解释器对外将__name变量改成_Student__name。访问_Student__name还是可以访问__name变量。
类似:__XXX__是特殊变量,可以直接引用,但是有特殊用途,如if __name__ == '__main__':,我们自己变量一般不用这种变量名。
_XXX和__XXX这样的函数和变量“不应该”被直接引用。

3、继承与多态
从现有的class继承,新的class称为子类。被继承的class称为基类、父类、或超类。如:
class Animal(object):
      def run(self):
      print('Animal is running...')
Dog,Cat从Animal继承:
class Dog(Animal):  
    pass
class Cat(Animal): 
    pass

作用:
(1)继承类获得父类的全部功能;Dog,Cat都有run()方法,也可以增加自己的方法。
(2)可以对继承方法修改。当子类和父类都有同一方法时,调用时,子类覆盖父类的方法。提现继承的多态性,一个Dog实例化的对象,即是属于Dog类,也属于Animal类。
(3)继承可以一级一级继承下来。因此一个类可以继承多个类的特性。

4、动态语言和静态语言
      编写一个接受Animal类型的变量
      def run_twice(animal): 
             animal.run() 
             animal.run()
可以对实例后传参,run_twice(Dog())、run_twice(Cat());
    对于静态语言,如果需要传入Animal类型,则传入对象必须是Animal类或者它的子类,否则不能调用run方法。但是对于python这种动态语言而言,只需要保证传入对象有一个run()方法就可以了。
    class Timer(object):
          def run(self):
              print('Start...')
     因此也能调用run_twice函数调用run()方法。run_twice(Timer())。也就是只要一个对象“看起来像鸭子,走起路来像鸭子”,那它就可以看做鸭子。

5、获取对象信息
(1)type():判断对象类型;
(2)isinstance():判断class的类型,判断一个对象是否属于某个类。能用type判断的类型也能用isinstance()判断。
(3)dir():获取一个对象的所有属性和方法。
(4)之前说的__xxx__有特殊作用,比如__len__方法,我们调用len()函数获取对象长度时,len()函数内部会自动调用__len__()方法。
因此,计算len('ABC')等价'ABC'.__len__()
(5)利用getattr()、setattr、hasattr可以直接操作对象的状态。
hasattr():判断是否有某个属性;
getattr():获取属性值
setattr():设置一个属性值。

三、Python高级属性
1、__slots__
定义一个class,创建实例后,我们可以给实例绑定任何属性和方法。由于动态语言的灵活性。
class Student(object):
    pass
实例化,s = Student()
s.name = 'Michiael'
或绑定方法
def set_age(self,age):
    self.age  = age
from types  import MethodType
s.set_age = MethodType(set_age,s)
但是给一个实例绑定的方法,在另一个实例中不起作用。
如果需要限制实例的属性,只允许name和age属性。可以用__slots__变量限制。
class Student(object):
    __slots__ = ('name','age')
__slots__定义属性只对当前实例起作用,对于继承的子类不起作用。

2、@property
在绑定属性时,属性的值可以随便改动,无法检查参数。如 s.score = 9999,需要限制score范围,因此可以设置set_score()和get_score()获取成绩
class Student(object):
      def get_score(self):
          return self._score
      def set_score(self, value):
           if not isinstance(value, int):
                raise ValueError('score must be an integer!')
           if value < 0 or value > 100:
                raise ValueError('score must between 0 ~ 100!')
          self._score = value
s = Student()后,s.set_score(60)是正常的,s.set_score(9999)会报错。
    但是这种限制方法,调用比较复杂,是否能实现s.score = 9999这样简单的访问变量,又能检查参数,python的@property能够实现,它是将一个方法变成属性调用。
class Student(object):
    @property
    def score(self):
          return self._score
    @score.setter
    def score(self, value):
          if not isinstance(value, int):
                raise ValueError('score must be an integer!')
           if value < 0 or value > 100:
                raise ValueError('score must between 0 ~ 100!')
           self._score = value
上面将getter方法变成了属性值,@property又创建一个装饰器@score.setter将setter方法变成属性赋值。

3、多重继承
      一个子类可以继承多个父类,通过多重继承,一个子类就可以同时获得多个父类的所有功能。
      通常类的继承关系。都是主线单一继承下来的。这样在继承多个类时,会导致复杂而庞大的继承链。如果需要混入额外的功能,可以进行同时继承多个类,这种设计成为Mixin。
如:
class Dog(Mammal,RunnableMinxIN,  \
  CarnivorousMixin):
    pass

4、定制类
      Pythonc的class中有许多特殊用途的函数,可帮助定制类。
(1)__str__:显示字符
(2)__iter__:需要设置一个类,像for ...in循环访问,类似list或tuple,需要实现__iter__方法。
(3)__getitem__:虽然实现__iter__能够作用for循环,但是还是不能像list那样取元素,如果想像list按照下标取出元素,需要实现__getitem__方法。
def __getitem__(self, n):
    a, b = 1, 1
    for x in range(n):
        a, b = b, a + b
    return a
(4)__getattr__:python调用不存在的属性时,一般程序会报错,如果加入__getattr__,Python试图调用,来获取属性。
(5)__call__:调用实例方法时,是通过instance.method()调用,通过__call__可实现在实例本身调用。或者说,将类对象当做函数使用。如:
class DistanceForm(object):
    def __init__(self, origin):
        self.origin = origin
        print "origin :"+str(origin)
    def __call__(self, x):
        print "x :"+str(x)
    p = DistanceForm(100)
    p(2000) #类似函数方式,直接赋值调用。
python还有很多定制方法。可查官网。

5、使用元类
    type()函数既可以返回一个对象的类型,也可以创建一个新的类型。比如可以用type创建一个类。
    Hello = type('Hello', (object,), dict(hello=fn))
创建的参数:
(1)class的名称;
(2)继承的父类集合,注意Python支持多重继承,如果只有一个父类,别忘了tuple的单元素写法;
(3)class的方法名称与函数绑定,这里我们把函数fn绑定到方法名hello上。除了通过type()动态创建类外,还可以是使用mataclass。元类是类的类。一个实例创建的完整过程应该是,先创建一个元类,元类创建类,类创建实例。
    type函数实际就是一个元类,也是Python背后创建所有类的元类。
我们可以自定义元类:
# metaclass是类的模板,所以必须从`type`类型派生:
class ListMetaclass(type):
    def __new__(cls, name, bases, attrs):
        attrs['add'] = lambda self, value: self.append(value)
        return type.__new__(cls, name, bases, attrs)
class MyList(list, metaclass=ListMetaclass):    pass
Mylist创建时,是通过ListMetaclass.__new__创建。因此可以修改类的定义,或加入新方法。
__new__()方法接收到的参数依次是:
1、当前准备创建的类的对象;
2、类的名字;
3、类继承的父类集合;
4、类的方法集合。
实例化:
L = MyList()   此时可以实现 add调用。L.add(1)

四、Python小实践
    实现模式向kindle中推送任意数量本地书籍:
# sendmail.py
from email.mime.text import MIMEText
from email.mime.multipart import MIMEMultipart
import smtplib
from os.path import basename

from_addr = "xxxxxx@126.com"
password = "######"
to_addr = "xxxxxx@kindle.cn"
smtp_server = "smtp.126.com"

def send_mail(attachments=None):
   msg = MIMEMultipart()
   msg['Subject'] = "SendingBook"
   msg['From'] = from_addr
   msg['To'] = to_addr
   msg['Accept-Language'] = 'zh-CN,utf-8'
   msg['Accept-Charset'] = 'ISO-8859-1,utf-8'  
   attachments = [ "D:/电子书/kindle/"+x for x in attachments] 
   for attachment in attachments or []:
      files=attachment
      file_name = basename(attachment)
      attr = MIMEText(open('%s'%files,'rb').read(),'base64','utf-8')
      attr["Content-Type"] = 'application/octet-stream'
      attr["Content-Disposition"] = 'attachment;filename="%s"'%file_name
      msg.attach(attr)
   server = smtplib.SMTP(smtp_server)
   server.starttls()
   server.login(from_addr,password)
   server.sendmail(from_addr,to_addr,msg.as_string())
   server.quit()
if __name__=='__main__':
  import sys
  if len(sys.argv) > 1:
     attachment = sys.argv[1:]
  else:
     attachment = []
  send_mail(attachment) 
调用方法:python sendmail.py Python-web-spider.mobi ,目前调用时,存在一个问题,书籍名中不支持中文。

参考地址:http://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000

欢迎加入本站公开兴趣群
软件开发技术群
兴趣范围包括:Java,C/C++,Python,PHP,Ruby,shell等各种语言开发经验交流,各种框架使用,外包项目机会,学习、培训、跳槽等交流
QQ群:26931708

Hadoop源代码研究群
兴趣范围包括:Hadoop源代码解读,改进,优化,分布式系统场景定制,与Hadoop有关的各种开源项目,总之就是玩转Hadoop
QQ群:288410967 

鲜花

握手

雷人

路过

鸡蛋

相关阅读

最新评论

热门频道

  • 大数据
  • 商业智能
  • 量化投资
  • 科学探索
  • 创业

即将开课

 

GMT+8, 2018-2-19 01:56 , Processed in 0.156590 second(s), 25 queries .