前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >ARTS第二周

ARTS第二周

作者头像
zx钟
发布2019-07-18 21:53:53
3890
发布2019-07-18 21:53:53
举报
文章被收录于专栏:测试游记

Algorithm主要是为了编程训练和学习。每周至少做一个 leetcode 的算法题(先从Easy开始,然后再Medium,最后才Hard)。进行编程训练,如果不训练你看再多的算法书,你依然不会做算法题,看完书后,你需要训练。关于做Leetcode的的优势,你可以看一下我在coolshell上的文章 Leetcode 编程训练 - 酷 壳 - CoolShell。 Review:主要是为了学习英文,如果你的英文不行,你基本上无缘技术高手。所以,需要你阅读并点评至少一篇英文技术文章,我个人最喜欢去的地方是http://Medium.com 以及各个公司的技术blog,如Netflix的。 Tip:主要是为了总结和归纳你在是常工作中所遇到的知识点。学习至少一个技术技巧。你在工作中遇到的问题,踩过的坑,学习的点滴知识。 Share:主要是为了建立你的影响力,能够输出价值观。分享一篇有观点和思考的技术文章。

Algorithm

给出一个 32 位的有符号整数,你需要将这个整数中每位上的数字进行反转。

示例 1:

代码语言:javascript
复制
输入: 123
输出: 321

示例 2:

代码语言:javascript
复制
输入: -123
输出: -321

示例 3:

代码语言:javascript
复制
输入: 120
输出: 21

注意:

假设我们的环境只能存储得下 32 位的有符号整数,则其数值范围为 [−2^31, 2^31 − 1]。请根据这个假设,如果反转后整数溢出那么就返回 0。

代码语言:javascript
复制
import math
class Solution:
    def reverse(self, x: int) -> int:
        if x > 0:
            i = int(math.log10(x))+1
            flag = 1
        elif x < 0:
            flag = -1
            i = int(math.log10(-x))+1
            x = -x
        elif x == 0:
            return 0
        test_dict = {}
        while i >= 0:
            test_dict[i] = x % 10
            i -= 1
            x = x // 10
        new_num = 0
        for key,value in test_dict.items():
            new_num += value * pow(10,key-1)
        if int(new_num) * flag > pow(2,31) -1 or int(new_num) * flag < -pow(2,31):
            return 0
        return int(new_num) * flag

写完我都不知道自己在干啥了,速度上还可以,但是空间占用上就不行了。

执行情况

速度分布

借鉴一下执行速度最快的代码:

代码语言:javascript
复制
class Solution:
    def reverse(self, x: int) -> int:
        rev = 0
        while x != 0:
            pop = x % 10 - 10 if x < 0 and x % 10 != 0 else x % 10
            x = int(x / 10)
            if rev > (2 ** 31 - 1) / 10:
                return 0
            if rev < - (2 ** 31) / 10:
                return 0
            rev = rev * 10 + pop
        return rev

分析一下pop

代码语言:javascript
复制
pop = x % 10 - 10 if x < 0 and x % 10 != 0 else x % 10
# 等价于
if x < 0 and x % 10 != 0: # 负数和10的倍数
   pop = x % 10 -10
else
    pop = x % 10

Review

一直觉得python的元类很神奇,所以本次阅读一篇关于元类的介绍

What are metaclasses in Python?

https://stackoverflow.com/questions/100003/what-are-metaclasses-in-python

A metaclass is the class of a class.

类定义了实例对象的行为方式,元类定义了类的行为方式。类就是元类的实例对象。

A metaclass is most commonly used as a class-factory. When you create an object by calling the class, Python creates a new class (when it executes the 'class' statement) by calling the metaclass. Python通过元类声明一个新的类。

声明class的过程中,Python会像执行一个代码块一样执行它,它的结果是一个保存属性的命名空间(字典)。

This object (the class) is itself capable of creating objects (the instances), and this is why it's a class.

普通方式创建一个类:

代码语言:javascript
复制
>>> class MyShinyClass(object):
...       pass

使用type创建一个类

代码语言:javascript
复制
>>> MyShinyClass = type('MyShinyClass', (), {}) # returns a class object
>>> print(MyShinyClass)
<class '__main__.MyShinyClass'>
>>> print(MyShinyClass()) # create an instance with the class
<__main__.MyShinyClass object at 0x8997cec>

type接收字典作为类属性

代码语言:javascript
复制
# 普通方式构造一个Foo类
>>> class Foo(object):
...       bar = True

# 通过type的方式构造Foo类
>>> Foo = type('Foo', (), {'bar':True})

type接收对象作为父类

代码语言:javascript
复制
# 普通方式构造一个Foo的子类FooChild
>>>   class FooChild(Foo):
...         pass

# 通过type的方式构造一个Foo的子类FooChild
>>> FooChild = type('FooChild', (Foo,), {})
>>> print(FooChild)
<class '__main__.FooChild'>

# 查看FooChild的父类Foo的类属性bar
>>> print(FooChild.bar) # bar是上一个例子Foo中的类属性
True

type接收函数对象作为类方法

代码语言:javascript
复制
# 定义一个方法echo_bar
>>> def echo_bar(self):
...       print(self.bar)

# 使用type的方式构建一个包含echo_bar方法的类
>>> FooChild = type('FooChild', (Foo,), {'echo_bar': echo_bar})

# 测试
>>> hasattr(Foo, 'echo_bar')
False
>>> hasattr(FooChild, 'echo_bar')
True
>>> my_foo = FooChild()
>>> my_foo.echo_bar()
True

所以!也可以动态的通过这种方法增加类方法

代码语言:javascript
复制
>>> def echo_bar_more(self):
...       print('yet another method')
...
>>> FooChild.echo_bar_more = echo_bar_more
>>> hasattr(FooChild, 'echo_bar_more')
True

Everything, and I mean everything, is an object in Python.

In Python2
代码语言:javascript
复制
class Foo(object):
    __metaclass__ = something...
    [...]
In Python3
代码语言:javascript
复制
class Foo(object, metaclass=something):
    pass

class Foo(object, metaclass=something, kwarg1=value1, kwarg2=value2):
    pass

把类属性都变成大写的元类

代码语言:javascript
复制
# the metaclass will automatically get passed the same argument
# that you usually pass to `type`
def upper_attr(future_class_name, future_class_parents, future_class_attr):
    """
      Return a class object, with the list of its attribute turned
      into uppercase.
    """

    # pick up any attribute that doesn't start with '__' and uppercase it
    uppercase_attr = {}
    for name, val in future_class_attr.items():
        if not name.startswith('__'):
            uppercase_attr[name.upper()] = val
        else:
            uppercase_attr[name] = val

    # let `type` do the class creation
    return type(future_class_name, future_class_parents, uppercase_attr)


__metaclass__ = upper_attr  # this will affect all classes in the module


class Foo():  # global __metaclass__ won't work with "object" though
    # but we can define __metaclass__ here instead to affect only this class
    # and this will work with "object" children
    bar = 'bip'


print(hasattr(Foo, 'bar'))
# Out: False
print(hasattr(Foo, 'BAR'))
# Out: True

f = Foo()
print(f.BAR)
# Out: 'bip'

The reason behind the complexity of the code using metaclasses is not because of metaclasses, it's because you usually use metaclasses to do twisted stuff relying on introspection, manipulating inheritance, vars such as __dict__, etc. 元类好像就这么简单,之所以复杂是由于我们用它来进行了复杂的操作

中文翻译的文档:https://www.cnblogs.com/tkqasn/p/6524879.html

Django的ORM例子

定义用户表:

代码语言:javascript
复制
class Person(models.Model):
    name = models.CharField(max_length=30)
    age = models.IntegerField()

实例化:

代码语言:javascript
复制
guy = Person(name='bob', age='35')
print(guy.age)
# It won't return an IntegerField object. 
# It will return an int.
# can even take it directly from the database.

由于models.Model定义了__metaclass__

Django的源码:

https://github.com/django/django/blob/master/django/db/models/base.py#L399

class Model(metaclass=ModelBase):从类的声明处可以发现它的元类是ModelBase

找到定义ModelBase的地方可以看到:class ModelBase(type):它继承了type类。不过源码太复杂了,阅读一下阉割版的。

代码语言:javascript
复制
#coding:utf-8
#一、首先来定义Field类,它负责保存数据库表的字段名和字段类型:
class Field(object):
    def __init__(self, name, column_type):
        self.name = name
        self.column_type = column_type
    def __str__(self):
        return '<%s:%s>' % (self.__class__.__name__, self.name)

class StringField(Field):
    def __init__(self, name):
        super(StringField, self).__init__(name, 'varchar(100)')

class IntegerField(Field):
    def __init__(self, name):
        super(IntegerField, self).__init__(name, 'bigint')

#二、定义元类,控制Model对象的创建
class ModelMetaclass(type):
    '''定义元类'''
    def __new__(cls, name, bases, attrs):
        if name=='Model':
            return super(ModelMetaclass,cls).__new__(cls, name, bases, attrs)
        mappings = dict()
        for k, v in attrs.iteritems():
            # 保存类属性和列的映射关系到mappings字典
            if isinstance(v, Field):
                print('Found mapping: %s==>%s' % (k, v))
                mappings[k] = v
        for k in mappings.iterkeys():
            #将类属性移除,使定义的类字段不污染User类属性,只在实例中可以访问这些key
            attrs.pop(k)
        attrs['__table__'] = name.lower() # 假设表名为类名的小写,创建类时添加一个__table__类属性
        attrs['__mappings__'] = mappings # 保存属性和列的映射关系,创建类时添加一个__mappings__类属性
        return super(ModelMetaclass,cls).__new__(cls, name, bases, attrs)

#三、编写Model基类
class Model(dict):
    __metaclass__ = ModelMetaclass

    def __init__(self, **kw):
        super(Model, self).__init__(**kw)

    def __getattr__(self, key):
        try:
            return self[key]
        except KeyError:
            raise AttributeError(r"'Model' object has no attribute '%s'" % key)

    def __setattr__(self, key, value):
        self[key] = value

    def save(self):
        fields = []
        params = []
        args = []
        for k, v in self.__mappings__.iteritems():
            fields.append(v.name)
            params.append('?') # 这里其实应该是args
            args.append(getattr(self, k, None))
        sql = 'insert into %s (%s) values (%s)' % (self.__table__, ','.join(fields), ','.join(params))
        print('SQL: %s' % sql)
        print('ARGS: %s' % str(args))

#最后,我们使用定义好的ORM接口,使用起来非常的简单。
class User(Model):
    # 定义类的属性到列的映射:
    id = IntegerField('id')
    name = StringField('username')
    email = StringField('email')
    password = StringField('password')

# 创建一个实例:
u = User(id=12345, name='Michael', email='test@orm.org', password='my-pwd')
# 保存到数据库:
u.save()

#输出
# Found mapping: email==><StringField:email>
# Found mapping: password==><StringField:password>
# Found mapping: id==><IntegerField:id>
# Found mapping: name==><StringField:username>
# SQL: insert into User (password,email,username,id) values (?,?,?,?)
# ARGS: ['my-pwd', 'test@orm.org', 'Michael', 12345]

Tip

最近搭建了Gitlab的CI,想进行代码质量的审核,采用的是flask8,但是使用发现.flask8文件一直无法生效,最终采用了直接菜CI流水线中写入一整行的flask8校验语句:

代码语言:javascript
复制
$ flake8 --ignore D203 \
         --exclude .git,__pycache__,docs/source/conf.py,old,build,dist \
         --max-complexity 10

另外:Docker搭建gitlab runner的方法

代码语言:javascript
复制
# 拉取镜像
$ sudo docker pull gitlab/gitlab-runner:latest
# 启动容器
$ sudo docker run -d --name gitlab-runner --restart always \
  -v /srv/gitlab-runner/config:/etc/gitlab-runner \
  -v /var/run/docker.sock:/var/run/docker.sock \
  gitlab/gitlab-runner:latest
# 注册Gitlab runner
$ sudo docker exec -it gitlab-runner gitlab-ci-multi-runner register
# 进入容器内部查看状态
$ sudo docker exec -it gitlab-runner /bin/bash
# 退出,但不关闭容器
Ctrl+P+Q

具体注册方法参考以下两篇文档:

  • https://idig8.com/2018/08/22/zhongjipiandockerzhici-cdchixujichenggitlab-cifuwuqi71/
  • https://idig8.com/2018/08/30/zhongjipiandockerzhici-cdchixujichengzhenshipythonxiangmudeciyanshi72/

Share

阅读了一些外文文档然后输出的:Git基础知识(七)--分支开发工作流:https://mp.weixin.qq.com/s/xcYMzdHXgFr6BUoWHAq69w 欢迎关注我的公众号:zx94_11

本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-04-10,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 测试游记 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Algorithm
  • Review
    • What are metaclasses in Python?
      • In Python2
        • In Python3
          • 把类属性都变成大写的元类
            • Django的ORM例子
            • Tip
            • Share
            相关产品与服务
            容器服务
            腾讯云容器服务(Tencent Kubernetes Engine, TKE)基于原生 kubernetes 提供以容器为核心的、高度可扩展的高性能容器管理服务,覆盖 Serverless、边缘计算、分布式云等多种业务部署场景,业内首创单个集群兼容多种计算节点的容器资源管理模式。同时产品作为云原生 Finops 领先布道者,主导开源项目Crane,全面助力客户实现资源优化、成本控制。
            领券
            问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档