金融量化学习---Python, MySQL, Pandas

这里用来记录一些在金融领域,尤其是银行相关的资金、债券、票据中应用到的数据管理与分析, 编程等心得或笔记,以及个人的一点小小兴趣(易经八卦、藏密禅修)等

导航

python 的“类”的应用

一、介绍: 类与实例

类(Class): 用来描述具有相同的属性和方法的对象的集合。它定义了该集合中每个对象所共有的属性和方法。对象是类的实例。
类变量:类变量在整个实例化的对象中是公用的。类变量定义在类中且在函数体之外。类变量通常不作为实例变量使用。
数据成员:类变量或者实例变量用于处理类及其实例对象的相关的数据。
方法重写:如果从父类继承的方法不能满足子类的需求,可以对其进行改写,这个过程叫方法的覆盖(override),也称为方法的重写。
实例变量:定义在方法中的变量,只作用于当前实例的类。
继承:即一个派生类(derived class)继承基类(base class)的字段和方法。继承也允许把一个派生类的对象作为一个基类对象对待。例如,有这样一个设计:一个Dog类型的对象派生自Animal类,素以Dog也是一个Animal。
实例化:创建一个类的实例,类的具体对象。
方法:类中定义的函数。
对象:通过类定义的数据结构实例。对象包括两个数据成员(类变量和实例变量)和方法。
和其它编程语言相比,Python 在尽可能不增加新的语法和语义的情况下加入了类机制。

类有这样一些的优点:

1、类对象是多态的:也就是多种形态,这意味着我们可以对不同的类对象使用同样的操作方法,而不需要额外写代码。
2、类的封装:封装之后,可以直接调用类的对象,来操作内部的一些类方法,不需要让使用者看到代码工作的细节。
3、类的继承:类可以从其它类或者元类中继承它们的方法,直接使用。

二、类的定义

1.定义类(class)的语法

class Iplaypython:
    def __init__(self):
    def fname(self, name):
    self.name = name

第一行,语法是class 后面紧接着,类的名字,最后别忘记“冒号”,这样来定义一个类。
类的名字,首字母,有一个不可文的规定,最好是大写,这样需要在代码中识别区分每个类。
第二行开始是类的方法,大家看到了,和函数非常相似,但是与普通函数不同的是,它的内部有一个“self”,参数,它的作用是对于对象自身的引用。

2.初始化对象

创建类时,可以定义一个特定的方法,名为__init__(),只要创建这个类的一个实例就会运行这个方法。可以向__init__()方法传递参数,这样创建对象时就可以把属性设置为你希望的值__init__()这个方法会在创建对象时完成初始化

class peo:
    def __init__(self,name,age,sex):
        self.Name = name
        self.Age = age
        self.Sex = sex
    def speak(self):
        print("my name" + self.Name)

实例化这个类的对象时:

zhangsan=peo("zhangsan",24,'man')
print zhangsan.Age
24
print zhangsan.Name
zhangsan
print zhangsan.Sex
man

之前多次用到self这个形参类就好比是一张蓝图,使用一个类可以创建多个对象实例,speak()方法在被调用时,必须知道是哪个对象调用了它.

这里self参数就会告诉方法是哪个对象来调用的.这称为实例引用。

3.类的私有属性:

  __private_attrs 两个下划线开头,声明该属性为私有,不能在类地外部被使用或直接访问。在类内部的方法中使用时 self.__private_attrs
类的方法
  在类地内部,使用def关键字可以为类定义一个方法,与一般函数定义不同,类方法必须包含参数self,且为第一个参数
私有的类方法
  __private_method 两个下划线开头,声明该方法为私有方法,不能在类地外部调用。在类的内部调用slef.__private_methods
从类中的变量访问开始讲起,如下, 那么我们要如何访问这个变量呢?

定义类变量

class variable:
    a = '我是类变量'
 
    def showvarible(self):
        b = '我是函数变量'
        print(a)
        print(b)
variable().showvarible()

毫无疑问,编译器就已经报错了,这是因为类中的变量不可以在函数中直接访问,应该这样

class variable:
    a = '我是类变量'
    def showvarible(self):
        b = '我是函数变量'
        print(variable.a)
        print(b)

variable().showvarible()
我是类变量
我是函数变量

其实我们还可以通过self去访问

class variable:
    a = '我是类变量'
    def showvarible(self):
        b = '我是函数变量'
        print(self.a)
        print(b)
variable().showvarible()

#结果是一样的,输出:
我是类变量
我是函数变量

还可以怎么做呢,我们通过构造函数给定一个参数,类中可访问

class variable:
 
    def __init__(self,a):
        self.a = '我是类变量'
 
    def showvarible(self):
        b = '我是函数变量'
        print(self.a)
        print(b)

variable(1).showvarible()
我是类变量
我是函数变量

这里需要注意的是,实例化的时候必须给参数,由于python是动态语言,不需要指定参数的类型,你可以放int,比如1,也可以给一个字符串。

起步:定义一个类:

class FinancialInstrument(object):
    author = 'John C'
    def __init__(self,symbol,price):
        self.symbol = symbol
        self.price = price

FinancialInstrument.author
Out[1]: 'John C'

a = FinancialInstrument('Apple',100)
a
Out[2]: <__main__.FinancialInstrument at 0x1e4236182b0>

a.symbol
Out[3]: 'Apple'

a.price
Out[4]: 100

接上例:

class FinancialInstrument(FinancialInstrument):    #同名,继承上一个类
    def get_price(self):    #定义方法读取实例的属性值
        return self.price
    def set_price(self,price):  #定义方法修改实例的属性值
        self.price = price
        #return self.price  #加上这一句,运行后会有提示

fi = FinancialInstrument('Appl',105)

fi.author #通过继承,得到了上一个类的属性
Out[1]: 'John C'

fi.price
Out[2]: 105

fi.symbol
Out[3]: 'Appl'

fi.get_price()
Out[4]: 105

fi.set_price(99)  #更新实例后,可以发现属性值已经修改

fi.get_price()
Out[5]: 99

私有实例属性

一个新的例子:

class FinancialInstrument(object):
    author = 'John C'
    def __init__(self,symbol,price):
        self.symbol = symbol
        self.__price = price       #将它定义为私有实例属性
    def get_price(self):
        return self.__price
    def set_price(self,price):
        self.__price = price

fi = FinancialInstrument('Appl',105)

fi.get_price
Out[1]: <bound method FinancialInstrument.get_price of <__main__.FinancialInstrument object at 0x000001E4238EA640>>

fi.get_price()
Out[2]: 105

fi.__price  #这种情况不能直接引用
Traceback (most recent call last):
  File "<ipython-input-51-e3138907ce6c>", line 1, in <module>
    fi.__price
AttributeError: 'FinancialInstrument' object has no attribute '__price'

#换一种方式还是可以引用并且修改:
fi._FinancialInstrument__price
Out[3]: 105

fi._FinancialInstrument__price = 99
fi.get_price()
Out[4]: 99

类在金融工具中的应用

投资组合中常用到聚类的概念,下面用个例子来说明:

class PortfolioPosition(object):
    def __init__(self,financial_instrument,position_size):
        self.position = financial_instrument
        self.__position_size = position_size
    def get_position_size(self):
        return self.__position_size
    def update_position_size(self):
        self.__position_size = position_size
    def get_position_value(self):
        return self.__position_size * \
            self.position.get_price()    #根据属性计算头寸价值
#运行:
ps = PortfolioPosition(fi,10)  #注意:上例中 fi.get_price()= 99

ps
Out[1]: <__main__.PortfolioPosition at 0x1e42360ac70>

ps.get_position_size()
Out[2]: 10

ps.get_position_value()  #根据属性计算头寸价值
Out[3]: 990

ps.position   #ps.position就是fi
Out[4]: <__main__.FinancialInstrument at 0x1e4238ea640>

fi
Out[5]: <__main__.FinancialInstrument at 0x1e4238ea640>

ps.position.get_price()
Out[6]: 99

ps.position.set_price(105)   #更新金融工具价格

ps.get_position_value()
Out[7]: 1050

类的显化

一般的类,引用的时候显示的是内存地址,如何让它显示你想要显示的结果呢?这里要用到__repr__特殊方法

class Vector(object):
    def __init__(self,x=0,y=0,z=0):
        self.x = x
        self.y = y
        self.z = z
#输出:
v=Vector(1,2,3)

v
Out[0]: <__main__.Vector at 0x1e4203a1250>

#如果我们不喜欢这种显示方式,想要换一种,可以这样(续上例):
class Vector(Vector):   #继续上例的类
    def __repr__(self):
        return 'Vector(%r,%r,%r)' %(self.x,self.y,self.z)

v=Vector(1,2,3)

v
Out[1]: Vector(1,2,3)

type(v)
Out[2]: __main__.Vector

在类中定义方法并互相引用

方法一 格式:类名.方法名(self)
注意:方法名内必须传入一个实例对象的指针,self后可根据方法定义放入适当实参

Stu.printName_Age(self)
Stu.printSchool(self)

方法二 格式:self.方法名(方法列表)
方法列表不应该包括self

self.printName_Age()
self.printSchool()

class Foo(object):
    def __init__(self,value):
        self.value = value
    def stat(self):
        print('i love you')
    def foo(self):
        print("'i'm foo")
        self.stat()
#输出:
p= Foo(3)

p
Out[1]: <__main__.Foo at 0x1e4234b2be0>

p.stat()
Out[2]:i love you

p.foo()
Out[2]:'i'm foo
i love you

#定义一个类a
class a():
    def __init__(self,input):
    	#定义一个实例属性
        self.height = input

	#定义一个实例方法,并给与返回值
    def A(self):
        p = self.height
        return p
        
	#定义另一个实例方法,该方法需要方法A中的返回值,则在方法B中这样调用
    def B(self):
        print(a.A(self))

u=a(1)
u.B()
#输出:
u
Out[1]: <__main__.a at 0x1e422acbe80>

u.B()
Out[2]:1

4. classmethod类方法

  1. 在python中.类方法 @classmethod 是一个函数修饰符,它表示接下来的是一个类方法,而对于平常我们见到的则叫做实例方法。 类方法的第一个参数cls,而实例方法的第一个参数是self,表示该类的一个实例。
  2. 普通对象方法至少需要一个self参数,代表类对象实例
    3)类方法有类变量cls传入,从而可以用cls做一些相关的处理。并且有子类继承时,调用该类方法时,传入的类变量cls是子类,而非父类。 对于类方法,可以通过类来调用,就像C.f(),有点类似C++中的静态方法, 也可以通过类的一个实例来调用,就像C().f(),这里C(),写成这样之后它就是类的一个实例了。
class info(object):

  @classmethod
  def sayclassmethod(cls):
    print 'say %s' % cls

  def saymethod(self):
    print 'say %s' % self
test = info()
test.saymethod()##实例调用方法
test.sayclassmethod()##实例调用类方法
info.saymethod(test)##类调用实例方法
info.sayclassmethod()##类调用类方法

大家对比运行下。

5.类的装饰器@property

第一只方法(推荐)

class Pager:
    def __init__(self,all_count):
        self.all_count=all_count
    @property         #装饰器装饰
    def all_pager(self):
        a,b=divmod(self.all_count,10)
        if a==0:
            return a
        else:
            return  a+1

    @all_pager.setter  #注意名称,是上面被装饰器装饰的方法
    def all_pager(self,value):  #方法名称与上面的相同
        print(value)

    @all_pager.deleter    #注意名称
    def all_pager(self):  #名称与上面保持一致
        print('hehe')
p=Pager(101)
ret=p.all_count#以访问类属性的方法访问对象的方法
print(ret)

下面看第二种方法

class Pager:
    def __init__(self,all_count):
        self.all_count=all_count
    def f1(self):
        return 123
    def f2(self,value):
        print('======')
    def f3(self):
        print('+++++++')

    foo=property(fget=f1,fset=f2,fdel=f3)
p=Pager(101)
ret=p.foo
p.foo='alex'
print(p.foo)
del p.foo

在该类中定义三个函数,分别用作赋值、取值、删除变量
property函数原型为property(fget=None,fset=None,fdel=None,doc=None),上例根据自己定义相应的函数赋值即可。

三、访问属性

您可以使用点号 . 来访问对象的属性。使用如下类的名称访问类变量:
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount

完整实例:

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
class Employee:
   '所有员工的基类'
   empCount = 0
 
   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount
 
   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary
 
"创建 Employee 类的第一个对象"
emp1 = Employee("Zara", 2000)
"创建 Employee 类的第二个对象"
emp2 = Employee("Manni", 5000)
emp1.displayEmployee()
emp2.displayEmployee()
print "Total Employee %d" % Employee.empCount
执行以上代码输出结果如下:

Name :  Zara ,Salary:  2000
Name :  Manni ,Salary:  5000
Total Employee 2
你可以添加,删除,修改类的属性,如下所示:

emp1.age = 7  # 添加一个 'age' 属性
emp1.age = 8  # 修改 'age' 属性
del emp1.age  # 删除 'age' 属性

你也可以使用以下函数的方式来访问属性:

getattr(obj, name[, default]) : 访问对象的属性。
hasattr(obj,name) : 检查是否存在一个属性。
setattr(obj,name,value) : 设置一个属性。如果属性不存在,会创建一个新属性。
delattr(obj, name) : 删除属性。
hasattr(emp1, 'age')    # 如果存在 'age' 属性返回 True。
getattr(emp1, 'age')    # 返回 'age' 属性的值
setattr(emp1, 'age', 8) # 添加属性 'age' 值为 8
delattr(emp1, 'age')    # 删除属性 'age'

Python内置类属性

dict : 类的属性(包含一个字典,由类的数据属性组成)
doc :类的文档字符串
name: 类名
module: 类定义所在的模块(类的全名是'main.className',如果类位于一个导入模块mymod中,那么className.module 等于 mymod)
bases : 类的所有父类构成元素(包含了一个由所有父类组成的元组)
Python内置类属性调用实例如下:

实例

#!/usr/bin/python
# -*- coding: UTF-8 -*-
 
class Employee:
   '所有员工的基类'
   empCount = 0
 
   def __init__(self, name, salary):
      self.name = name
      self.salary = salary
      Employee.empCount += 1
   
   def displayCount(self):
     print "Total Employee %d" % Employee.empCount
 
   def displayEmployee(self):
      print "Name : ", self.name,  ", Salary: ", self.salary
 
print "Employee.__doc__:", Employee.__doc__
print "Employee.__name__:", Employee.__name__
print "Employee.__module__:", Employee.__module__
print "Employee.__bases__:", Employee.__bases__
print "Employee.__dict__:", Employee.__dict__
执行以上代码输出结果如下:

Employee.__doc__: 所有员工的基类
Employee.__name__: Employee
Employee.__module__: __main__
Employee.__bases__: ()
Employee.__dict__: {'__module__': '__main__', 'displayCount': <function displayCount at 0x10a939c80>, 'empCount': 0, 'displayEmployee': <function displayEmployee at 0x10a93caa0>, '__doc__': '\xe6\x89\x80\xe6\x9c\x89\xe5\x91\x98\xe5\xb7\xa5\xe7\x9a\x84\xe5\x9f\xba\xe7\xb1\xbb', '__init__': <function __init__ at 0x10a939578>}

属性引用 使用 Python 中所有属性引用所使用的标准语法: obj.name。 有效的属性名称是类对象被创建时存在于类命名空间中的所有名称。 因此,如果类定义是这样的:

class MyClass:
    """A simple example class"""
    i = 12345

    def f(self):
        return 'hello world'

那么 MyClass.i 和 MyClass.f 就是有效的属性引用,将分别返回一个整数和一个函数对象。 类属性也可以被赋值,因此可以通过赋值来更改 MyClass.i 的值。 doc 也是一个有效的属性,将返回所属类的文档字符串: "A simple example class"。

类的 实例化 使用函数表示法。 可以把类对象视为是返回该类的一个新实例的不带参数的函数。 举例来说(假设使用上述的类):

x = MyClass() #创建类的新 实例 并将此对象分配给局部变量 x。
实例化操作(“调用”类对象)会创建一个空对象。 许多类喜欢创建带有特定初始状态的自定义实例。 为此类定义可能包含一个名为 init() 的特殊方法,就像这样:
def init(self):
self.data = []
当一个类定义了 init() 方法时,类的实例化操作会自动为新创建的类实例发起调用 init()。 因此在这个示例中,可以通过以下语句获得一个经初始化的新实例:

x = MyClass()
当然,init() 方法还可以有额外参数以实现更高灵活性。 在这种情况下,提供给类实例化运算符的参数将被传递给 init()。 例如,:

class Complex:
     def __init__(self, realpart, imagpart):
         self.r = realpart
         self.i = imagpart

x = Complex(3.0, -4.5)
x.r, x.i
(3.0, -4.5)

四、继承类定义

1.单继承

class <类名>(父类名)
<语句>

class childbook(book)
    age = 10

单继承示例

 class student(people):
        grade = ''
        def __init__(self,n,a,w,g):
            #调用父类的构函
            people.__init__(self,n,a,w)
            self.grade = g
        #覆写父类的方法
        def speak(self):
            print("%s is speaking: I am %d years old,and I am in grade %d"%(self.name,self.age,self.grade))

    s = student('ken',20,60,3)
    s.speak()

2.类的多重继承

class 类名(父类1,父类2,....,父类n)
<语句1>

需要注意圆括号中父类的顺序,若是父类中有相同的方法名,而在子类使用时未指定,python从左至右搜索,即方法在子类中未找到时,从左到右查找父类中是否包含方法

另一个类,多重继承之前的准备

class speaker():
    topic = ''
    name = ''
    def __init__(self,n,t):
        self.name = n
        self.topic = t
    def speak(self):
        print("I am %s,I am a speaker!My topic is %s"%(self.name,self.topic))

#多重继承  
class sample(speaker,student):
    a =''
    def __init__(self,n,a,w,g,t):
        student.__init__(self,n,a,w,g)
        speaker.__init__(self,n,t)

test = sample("Tim",25,80,4,"Python")
test.speak()#方法名同,默认调用的是在括号中排前地父类的方法

五、类的专业方法

Python 类可以定义专用方法,专用方法是在特殊情况下或当使用特别语法时由 Python 替你调用的,而不是在代码中直接调用(象普通的方法那样)。

1 init

类似于构造函数

#!/usr/local/bin/python
class Study:
        def __init__(self,name=None):
                self.name = name
        def say(self):
                print self.name
study = Study("Badboy")
study.say()

2 del

类似于析构函数

#!/usr/local/bin/python
class Study:
        def __init__(self,name=None):
                self.name = name
        def __del__(self):
                print "Iamaway,baby!"
        def say(self):
                print self.name
study = Study("zhuzhengjun")
study.say()

3__repr__

使用repr(obj)的时候,会自动调用__repr__函数,该函数返回对象字符串表达式,
用于重建对象,如果eval(repr(obj))会得到一个对象的拷贝。

#!/usr/local/bin/python
class Study:
        def __init__(self,name=None):
                self.name = name
        def __del__(self):
                print "Iamaway,baby!"
        def say(self):
                print self.name
        def __repr__(self):
                return "Study('jacky')"
study = Study("zhuzhengjun")
study.say()
print type(repr(Study("zhuzhengjun"))) # str
print type(eval(repr(Study("zhuzhengjun")))) # instance

study = eval(repr(Study("zhuzhengjun")))
study.say()

4__str__

Python能用print语句输出内建数据类型。有时,程序员希望定义一个类,要求它的对象也能用print语句输出。Python类可定义特殊方法__str__,为类的对象提供一个不正式的字符串表示。如果类的客户程序包含以下语句:

print objectOfClass
那么Python会调用对象的__str__方法,并输出那个方法所返回的字符串。

#!/usr/local/bin/python

class PhoneNumber:
        def __init__(self,number):
                 self.areaCode=number[1:4]
                 self.exchange=number[6:9]
                 self.line=number[10:14]

        def __str__(self):
                return "(%s) %s-%s"%(self.areaCode,self.exchange,self.line)

def test():
         newNumber=raw_input("Enter phone number in the form. (123) 456-7890: \n")
         phone=PhoneNumber(newNumber)
         print "The phone number is:"
         print phone

if__name__=="__main__":
         test()

方法__init__接收一个形如"(xxx) xxx-xxxx"的字符串。字符串中的每个x都是电话号码的一个位数。方法对字符串进行分解,并将电话号码的不同部分作为属性存储。
方法__str__是一个特殊方法,它构造并返回PhoneNumber类的一个对象的字符串表示。解析器一旦遇到如下语句:

print phone
就会执行以下语句:

print phone.str()
程序如果将PhoneNumber对象传给内建函数str(如str(phone)),或者为PhoneNumber对象使用字符串格式化运算符%(例如"%s"%phone),Python也会调用__str__方法。

5__cmp __

比较运算符,0:等于 1:大于 -1:小于

class Study:  
     def __cmp__(self, other):  
         if other > 0 :  
             return 1  
         elif other < 0:  
             return - 1  
         else:  
             return 0  
   
study = Study()  
if study > -10:print 'ok1'  
if study < -10:print 'ok2'  
if study == 0:print 'ok3' 

打印:ok2 ok3
说明:在对类进行比较时,python自动调用__cmp__方法,如-10 < 0 返回 -1,也就是说study 应该小与 -10,估打印ok2

6__getitem__

getitem 专用方法很简单。象普通的方法 clear,keys 和 values 一样,它只是重定向到字典,返回字典的值。

class Zoo:
     def __getitem__(self, key):
         if key == 'dog':return 'dog'
         elif key == 'pig':return  'pig'
         elif key == 'wolf':return 'wolf'
         else:return 'unknown'

zoo = Zoo()
print zoo['dog']
print zoo['pig']
print zoo['wolf']

打印 dog pig wolf

7__setitem__

setitem 简单地重定向到真正的字典 self.data ,让它来进行工作。

class Zoo:
     def __setitem__(self, key, value):
         print 'key=%s,value=%s' % (key, value)

zoo = Zoo()
zoo['a'] = 'a'
zoo['b'] = 'b'
zoo['c'] = 'c'
打印:
key=a,value=a
key=b,value=b
key=c,value=c

8 delitem

delitem 在调用 del instance[key] 时调用 ,你可能记得它作为从字典中删除单个元素的方法。当你在类实例中使用 del 时,Python 替你调用 delitem 专用方法。

class A:  
      def __delitem__(self, key):  
          print 'delete item:%s' %key  
    
a = A()  
del a['key'] 

9 其它特殊方法__len__, iter

class Vector(Vector):
    def __len__(self):
        return 3
    def __getitem__(self,i):   #使用索引值间接迭代
        if i in [0,-3]: return self.x
        elif i in [1,-2]: return self.y
        elif i in [2,-1]: return self.z
        else: raise IndexError('Index out of Range.')
#输出:
v = Vector(1,2,3)

len(v)
Out[1]: 3

v[0]
Out[2]: 1

v[-2]
Out[3]: 2

v[3]
Traceback (most recent call last):

  File "<ipython-input-105-f998c57dcc1e>", line 1, in <module>
    v[3]

  File "<ipython-input-99-27ebd3ef8e00>", line 8, in __getitem__
    else: raise IndexError('Index out of Range.')

IndexError: Index out of Range.

__iter__用来定义对象的元素在迭代时的行为,定义该对象为可迭代对象。所有的容器和集合都是可以迭代的。

class Vector(Vector):
    def __iter__(self):    #类实例上直接迭代
        for i in range(len(self)):
            yield self[i]

#输出:
v = Vector(1,2,3)

for i in range(len(v)):
    print(v[i])
Out[1]    
1
2
3

for i in v:
    print(i)
Out[2]    
1
2
3

10 ###abs()和bool()在类中的应用

abs()和bool()是两个标准函数,在Vector类上可通过特殊方法__abs__和__bool__定义:

class Vector(Vector):   #继续上例的类
    def __abs__(self):
        return (self.x ** 2 + self.y **2 + self.z **2)**0.5
    def __bool__(self):
        return bool(abs(self))
#输出:
v = Vector(1,2,-1)

abs(v)
Out[1]: 2.449489742783178

bool(v)
Out[2]: True

v = Vector()
v
Out[3]: Vector(0,0,0)

abs(v)
Out[4]: 0.0
  • 和 * 运算符可以用于几乎任何python对象,在类中可通过特殊方法__add__和__mul__定义:
class Vector(Vector):
    def __add__(self, other):
        x = self.x + other.x
        y = self.y + other.y
        z = self.z + other.z
        return Vector(x,y,z)
    def __mul__(self,scalar):
        return Vector(self.x * scalar,
                      self.y * scalar,
                      self.z * scalar)

#输出 :
v = Vector(1,2,3)

v
Out[1]: Vector(1,2,3)

v + Vector(2,3,4)
Out[2]: Vector(3,5,7)

v * 2
Out[3]: Vector(2,4,6)

作用域和命名空间示例

这个例子演示了如何引用不同作用域和名称空间,以及 global 和 nonlocal 会如何影响变量绑定:

def scope_test():
    def do_local():
        spam = "local spam"

    def do_nonlocal():
        nonlocal spam
        spam = "nonlocal spam"

    def do_global():
        global spam
        spam = "global spam"

    spam = "test spam"
    do_local()
    print("After local assignment:", spam)
    do_nonlocal()
    print("After nonlocal assignment:", spam)
    do_global()
    print("After global assignment:", spam)

scope_test()
print("In global scope:", spam)
示例代码的输出是:

After local assignment: test spam
After nonlocal assignment: nonlocal spam
After global assignment: nonlocal spam
In global scope: global spam

请注意 局部 赋值(这是默认状态)不会改变 scope_test 对 spam 的绑定。 nonlocal 赋值会改变 scope_test 对 spam 的绑定,而 global 赋值会改变模块层级的绑定。
您还可以在 global 赋值之前看到之前没有 spam 的绑定。

posted on 2021-02-07 16:53  chengjon  阅读(728)  评论(0编辑  收藏  举报